
문제출처
풀이
코드
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
int Find(vector<int>& s, int x) {
if ( s[x] == -1 ) {
return x;
}
return s[x] = Find(s, s[x]);
}
void Union(vector<int> &s, int x, int y , vector<int> &cost) {
int s_x = Find(s, x);
int c_x = cost[x];
cost[s_x] = min(c_x, cost[s_x]);
int s_y = Find(s, y);
int c_y = cost[y];
cost[s_y] = min(c_y, cost[s_y]);
if ( s_x == s_y ) {
return;
}
if ( s_x < s_y ) {
s[s_y] = s_x;
cost[s_x] = min(cost[s_y], cost[s_x]);
}
else {
s[s_x] = s_y;
cost[s_y] = min(cost[s_y], cost[s_x]);
}
}
return s[x] = Find(s,s[x]); 을 통해 랭크가 길어지지 않게끔 설계하였다.
Union에서는 cost비교를 하여 가장 적은 cost를 root에 달았다.
int main() {
ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
int N, M, K;
cin >> N >> M >> K;
int m = K;
vector<int> cost(N + 1);
vector<int> s(N + 1,-1);
vector<bool> check(N + 1, 0);
for ( int i = 1; i < N + 1; i++ ) {
cin >> cost[i];
}
for ( int i = 0; i < M; i++ ) {
int a, b;
cin >> a >> b;
Union(s, a, b,cost);
}
for ( int i = 1; i < N + 1; i++ ) {
int root = Find(s,i);
if ( check[root] == 1 )continue;
check[root] = 1;
K -= cost[root];
if ( K < 0 ) {
cout << "Oh no" << endl;
return 0;
}
}
cout << m - K << endl;
return 0;
}
for문을 통해 그룹내 최소 비용을 구하여 계산하였다.