/*
题意:
给你一个图,该图可能存在很多最小生成树。求最小生成树可能包含的边的个数。
思路:
这里我们将权值相同的边看成一个块,按块来处理。
按krusal的算法处理,检查每一块当该边加入后最小生成树后不会形成环就+1,
这里我们先不把他们加入,检查完后再将边加入,这样就能保证可能加入最小生成树的相同的权值的边都加入了,并且我们也计数了。
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100002;
int n,m,father[maxn],ans,sum,x,y;
struct node
{
int u,v,cost;
}p[500007];
int cmp(node a,node b)
{
return a.cost<b.cost;
}
int find(int x)
{
if (x != father[x])
father[x]=find(father[x]);
return father[x];
}
int main()
{
int i,j,k,u,v;
//freopen("din.txt","r",stdin);
while(scanf("%d%d",&n,&m)!=EOF)
{
ans=sum=0;
for(i=1;i<=n;i++)father[i]=i;
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&p[i].u,&p[i].v,&p[i].cost);
}
sort(p+1,p+m+1,cmp);
for(i=1;i<=m;i=j)
{
for(j=i;j<=m;j++)
{
if(p[i].cost!=p[j].cost)break;
x=find(p[j].u),y=find(p[j].v);
if(x!=y)
{
ans++;
}
}
for(k=i;k<j;k++)
{
x=find(p[k].u),y=find(p[k].v);
father[x]=y;
}
}
printf("%d\n",ans);
}
return 0;
}
sdut 2494 统计最小生成树的个数
最新推荐文章于 2024-02-11 13:52:22 发布