알고리즘 문제풀이/백준

[백준 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;
	

}