[题目大意]
给定一个无向图,求出这些边(至少出现在一棵生成树中的边)的数目。
[解题思路]
理解MST的思想,将贪心思想运用。
由小到大遍历这些边,权值相同的为一组。
先判断这些边是否能够成为树边,再对这些边进行合并。
[注意事项]
不知道为何,以前一直写的模板不顶用了...
一定要改成比较丑的样子...
[Code]
#include<iostream>
#include<cstdio>
#include<algorithm>
#define FF(i,N) for( int i=0;i<N;i++ )
using namespace std;struct edge{int u,v,len;
}E[111111];
int n,m;
int fat[111111];int getf( int x ){if( fat[x]==x ) return x;else return fat[x]=getf(fat[x]);
}bool cmp( edge a,edge b ){ return a.len<b.len; }
int krus()
{sort( E,E+m,cmp );memset( fat,0,sizeof(fat) );for( int i=0;i<=n;i++ ) fat[i]=i;int ret=0,pre=-1;for( int i=0;i<=m;i++ ){if( pre!=-1&&E[pre].len!=E[i].len ){for( int j=pre;j<i;j++ )if( getf(E[j].u)!=getf(E[j].v) )ret++;for( int j=pre;j<i;j++ )fat[getf(E[j].u)]=getf(E[j].v);//fat[fat[(E[j].u]]=fat[E[j].v];pre=-1;}if( pre==-1 )pre=i;}return ret;
}int main()
{int t;scanf("%d",&t);while( t-- ){scanf( "%d %d",&n,&m );E[m].len=INT_MAX;FF(i,m) scanf( "%d%d%d",&E[i].u,&E[i].v,&E[i].len );printf( "%d\n",krus() );}return 0;
}