FZU 2087 统计树边

[题目大意]

给定一个无向图,求出这些边(至少出现在一棵生成树中的边)的数目。

[解题思路]

理解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;
}


你可能感兴趣的:(FZU 2087 统计树边)