A:黑白边
- 并查集+贪心
- 贪心:优先读入黑边
- 并查集:存在不连通的情况就合并,并记录白边使用的次数
- 最后,判断是否为一组连通集,如果为一组那么输出白边次数,否则不构成两两连通,输出-1
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define mm(a,x) memset(a,x,sizeof a)
#define mk make_pair
#define ll long long
#define pii pair<int,int>
#define inf 0x3f3f3f3f
#define lowbit(x) (x) & (-x)
const int N = 2e5 + 10;
struct Node{
int a,b,c;
}node[N];
int n,m;
int fa[N];
void init(){
for(int i = 1; i < N; i ++ ){
fa[i] = i;
}
}
int find(int x){
if(fa[x] != x) fa[x] = find(fa[x]);
return fa[x];
}
void merge(int a,int b){
fa[find(a)] = find(b);
}
bool cmp(Node a,Node b){
return a.c < b.c;
}
int main() {
init();
cin >> n >> m;
for(int i = 0; i < m; i ++ ){
int a,b,c; cin >> a >> b >> c;
node[i] = {a,b,c};
}
sort(node,node + m,cmp);
int ans = 0;
for(int i = 0; i < m; i ++ ){
int a,b,c;
a = node[i].a,b = node[i].b; c = node[i].c;
if(find(a) != find(b)){
merge(a,b);
if(c == 1) ans ++;
}
}
set<int > s;
for(int i = 1; i <= n; i ++ ) s.insert(find(i));
if(s.size() == 1) cout<<ans;
else cout<<-1;
return 0;
}