牛牛的黑白边
n个点,m条边,每条边分为黑边和白边,现在需要挑一些边出来,使得n个点可以两两联通。由于牛牛特别讨厌白边,所以在挑中的边中,让白边最少,输出白边的条数,如果不能两两联通,输出−1.
链接:https://ac.nowcoder.com/acm/contest/9667/A
来源:牛客网
#include <iostream>
#include <algorithm>
#include <string>
#include <cmath>
#include <queue>
#define int long long
using namespace std;
const int maxn = 2e5 + 5;
int n,m,ans;
int f[maxn];
struct node{
int x,y,z;
}a[maxn];
bool cmp(node x, node y)
{
return x.z < y.z;
}
void init()
{
for(int i = 1; i <= n; i++) f[i] = i;
}
int getf(int a)
{
if(f[a] == a){
return a;
}else{
f[a] = getf(f[a]); //比如说4的爹是3,那就找3的爹
return f[a];
}
}
void merge(int a, int b, int z)
{
if(getf(b) != getf(a) && z == 1) ans++;//a 和 b
//之间可能已经被黑边链接了,就不需要用白边来连接了
f[getf(b)] = f[getf(a)];
}
signed main()
{
cin>>n>>m;
for(int i = 1; i <= m; i++){
cin>>a[i].x>>a[i].y>>a[i].z;
}
sort(a + 1, a + 1 + m, cmp);
init();
for(int i = 1; i <= m; i++){
merge(a[i].x, a[i].y, a[i].z);
}
int sum = 0;
for(int i = 1; i <= n; i++){
if(f[i] == i) sum++;
}
if(sum == 1) cout<<ans;
else cout<<"-1";
return 0;
}