MST Unification CodeForces - 1108F

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=2e5+10;
int n,m;
int p[N];
struct edge{
    int a,b;
    int w;
}e[N];
bool cmp(edge a,edge b)
{
    return a.w<b.w;
}
int find(int x)
{
    if(p[x]!=x)
        p[x]=find(p[x]);
    return p[x]; 
}
void Unit(int x,int y)
{
    int px=find(x);
    int py=find(y);
    if(px!=py)
        p[px]=py;
}
int main()
{
    while(cin>>n>>m)
    {
        for(int i=1;i<=n;i++)
            p[i]=i;
        for(int i=0;i<m;i++)
            cin>>e[i].a>>e[i].b>>e[i].w;
        sort(e,e+m,cmp);
        int ans=0;
        for(int i=0;i<m;)
        {
            int num=0;
            int j=i;
            //找到边权相同的尾部坐标
            while(e[i].w==e[j].w)
                j++;
            //从i到j都是边权最小且相同的边
            for(int k=i;k<j;k++)
            {
                int pa=find(e[k].a);
                int pb=find(e[k].b);
                //统计可以选择的合法边的数量
                if(pa!=pb)
                    num++;
            }
            for(int k=i;k<j;k++)
            {
                int pa=find(e[k].a);
                int pb=find(e[k].b);
                //从合法边中减去非冲突边(即可以被选入到同一个方案里,不互相冲突的边)
                //比如  有两条边是相同的
                //如果选择第一条之后,fx=fy
                //遍历到第二条时,num--就不能进行 
                if(pa!=pb)
                    Unit(pa,pb),num--;
            }
            i=j;
            //冲突边 = 合法边 - 非冲突边
            ans+=num;
        }
        cout<<ans<<endl;
    }
}

猜你喜欢

转载自www.cnblogs.com/QingyuYYYYY/p/12284231.html
MST