POJ 1679 The Unique MST 判断最小生成树唯一性

从一颗MST到另一颗MST只删除修改一条边再添加一条边

cnt1表示在权值相同时可以加入最小生成树的边数

cnt2表示在权值相同时被加入最小生成树的边数

如果可选择=加入则唯一

如果可选择>加入则不唯一

#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 200005;
int par[maxn];
struct node{int f,t;long long v;}zdy[maxn];
void Init(int n){for(int i=0;i<=n;i++)par[i]=i;}
int Find(int x)
{
    if(x==par[x]) return x;
    return par[x]= Find(par[x]);
}
void Union(int x,int y)
{
    x=Find(x),y=Find(y);
    if(x==y) return;
    par[x]=y;
}
bool cmp(node a,node b)
{
    return a.v<b.v;
}
int main()
{
    int n,m,T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        Init(n);
        for(int i=0;i<m;i++) scanf("%d%d%lld",&zdy[i].f,&zdy[i].t,&zdy[i].v);
        sort(zdy,zdy+m,cmp);
        int cnt1=0,cnt2=0,ans=0;
        for(int i=0;i<m;i++)
        {
            for(int j=i;j<m;j++)
            {
                if(zdy[i].v!=zdy[j].v) break;
                int t1=Find(zdy[j].f),t2=Find(zdy[j].t);
                if(t1!=t2) cnt1++;
            }
            for(int j=i;j<m;j++)
            {
                if(zdy[i].v!=zdy[j].v) break;
                int t1=Find(zdy[j].f),t2=Find(zdy[j].t);
                if(t1!=t2) cnt2++,Union(t1,t2),ans+=zdy[j].v;
            }

        }
        if(cnt1>cnt2) printf("Not Unique!\n");
        else printf("%d\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/ljq199926/article/details/81241182