[題目大意]
給定一個無向圖,求出這些邊(至少出現在一棵產生樹中的邊)的數目。
[解題思路]
理解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;}