题目链接
边可以分为2类,一类是可以构成MST,另一类是不可以的,用并查集做的时候,检查权重相同的边,但是2个端点不在同一个集合的时候,这个边就是可以选择的
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include<iostream>
using namespace std;
#define LL __int64
#define cl(a,b) memset(a,b,sizeof(a))
#define pb push_back
const int maxn = 2000005;
const int inf = 1<<28;
const __int64 mod = 1000000007;
int f[maxn];
void init(int n){
for(int i=0;i<=n;i++){
f[i]=i;
}
}
int Find(int x){
if(x==f[x])return x;
f[x]=Find(f[x]);
}
void Merge(int a,int b){
a=Find(a);
b=Find(b);
if(a==b)return;
f[a]=b;
}
bool same(int x,int y){
return Find(x)==Find(y);
}
struct node{
int x,y,z;
bool operator<(const node s) const {
return z<s.z;
}
}p[maxn];
int main(){
int T;scanf("%d",&T);
while(T--){
int n,m;scanf("%d%d",&n,&m);
init(n);
for(int i=0;i<m;i++){
int x,y,z;scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].z);
}
sort(p,p+m);
int ans(0);
for(int i=0;i<m;i++){
for(int j=i;j<m;j++)if(p[j].z==p[i].z){
if(!same(p[j].x,p[j].y))ans++;
}
else break;
for(int j=i;j<m;j++)if(p[j].z==p[i].z){
Merge(p[j].x,p[j].y);
}
else break;
}
printf("%d\n",ans);
}
return 0;
}