알고리즘 문제풀이/백준
[백준 13418] 학교 탐방하기
홍시홍
2020. 3. 9. 22:54
https://www.acmicpc.net/problem/13418
13418번: 학교 탐방하기
입력 데이터는 표준 입력을 사용한다. 입력은 1개의 테스트 데이터로 구성된다. 입력의 첫 번째 줄에는 건물의 개수 N(1≤N≤1,000)과 도로의 개수 M(1≤M≤n*(n-1)/2) 이 주어진다. 입력의 두 번째 줄부터 M+1개의 줄에는 A, B(1≤ A,B ≤ N), C 가 주어진다. 이는 A와 B 건물에 연결된 도로가 있다는 뜻이며, C는 0(오르막길) 또는 1(내리막길)의 값을 가진다. 같은 경로 상에 2개 이상의 도로가 주어지는 경우는 없으며, 입
www.acmicpc.net
요구사항
최악 피로도와 최소 피로도의 차이 구하기
풀이
오름차순으로 정렬하여 크루스칼 한번하고
내림차순으로 정렬하여 크루스칼 한번하여
각 각을 연결할때 가중치가 0이면 cnt++하여 계산한다.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct go {
int x;
int y;
int z;
};
int n, m;
vector<go> v;
bool com1(go a, go b) {
if (a.z < b.z) return true;
return false;
}
bool com2(go a, go b) {
if (a.z > b.z) return true;
return false;
}
int parent[100100];
int Find(int x) {
if (parent[x] == x) return x;
return parent[x] = Find(parent[x]);
}
void Union(int x, int y) {
x = Find(x);
y = Find(y);
if (x != y)
parent[x] = y;
}
int main() {
scanf("%d%d", &n, &m);
int fx, fy, fz;
int cntmax = 0;
int cntmin = 0;
int vertex = 0;
for (int i = 0; i < m+1; i++) {
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
if (x == 1 && y == 0) {
fz = z;
continue;
}
if (x == 0 && y == 1) {
fz = z;
continue;
}
v.push_back({ x,y,z });
}
for (int i = 1; i <= n; i++) {
parent[i] = i;
}
//max
if (fz == 0) cntmax++;
Union(0, 1);
sort(v.begin(), v.end(),com2);
for (int i = 0; i < v.size(); i++) {
int nowx = v.at(i).x;
int nowy = v.at(i).y;
int dist = v.at(i).z;
if (Find(nowx) != Find(nowy)) {
if (dist == 0)
cntmax++;
Union(nowx, nowy);
vertex++;
}
if (vertex == n - 1) break;
}
int maxdist = cntmax*cntmax;
if (fz == 0) cntmin++;
for (int i = 1; i <= n; i++) {
parent[i] = i;
}
Union(0, 1);
sort(v.begin(), v.end(), com1);
for (int i = 0; i < v.size(); i++) {
int nowx = v.at(i).x;
int nowy = v.at(i).y;
int dist = v.at(i).z;
if (Find(nowx) != Find(nowy)) {
if (dist == 0)
cntmin++;
Union(nowx, nowy);
vertex++;
}
if (vertex == n - 1) break;
}
int mindist = cntmin*cntmin;
cout << mindist - maxdist << endl;
}