FZU 2087 统计树边

来源:互联网 发布:淘宝手淘搜索一下爆 编辑:程序博客网 时间:2024/06/11 11:08

[题目大意]

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

[解题思路]

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


原创粉丝点击