poj1679次小生成树

来源:互联网 发布:linux下安装 seafile 编辑:程序博客网 时间:2024/05/17 23:23

次小生成树:是否存在多种情况的最小生成树

把最小生成树连的边保存起来,然后循环,不用其中任意一条边形成最小生成树跟原来答案是否一样

#include <iostream>#include <algorithm>#include <cstring>#include <string>#include <vector>#include <stdio.h>#include <math.h>using namespace std;#define FOR(i,j,k)   for(int i=j;i<=k;i++)const int mod= 1e9+7;int f[110];int find(int x){    int r=x,temp;    while(f[r]!=r)        r=f[r];    while(x!=r)    {        temp=f[x];        f[x]=r;        x=temp;    }    return x;}void unionset(int x,int y){    int xx=find(x),yy=find(y);    if(xx<yy) f[xx]=yy;    else f[yy]=xx;}struct node{    int x;    int y;    int w;    friend bool operator <(const node &nd1,const node &nd2)    {        return nd1.w<nd2.w;    }}nd[110*100];int edge[110];int main(){    int t;    scanf("%d",&t);    while(t--){        int n,m;        scanf("%d%d",&n,&m);        memset(edge,0,sizeof(edge));        for(int i=1;i<=n;i++)            f[i]=i;        for(int i=1;i<=m;i++)                scanf("%d%d%d",&nd[i].x,&nd[i].y,&nd[i].w);        sort(nd+1,nd+m+1);        int ans=0;        int k=0;        for(int i=1;i<=m;i++)        {            int xx=find(nd[i].x),yy=find(nd[i].y);            if(xx!=yy)            {                unionset(xx,yy);                ans+=nd[i].w;                k++;                edge[k]=i;            }        }        int flag=0;        FOR(i,1,n-1)        {            int ans2=0,bian2=0;            FOR(j,1,n) f[j]=j;            FOR(j,1,m)            {                if(j==edge[i])                    continue;                int xx=find(nd[j].x),yy=find(nd[j].y);                if(xx!=yy)                {                    unionset(xx,yy);                    ans2+=nd[j].w;                    bian2++;                }            }            if(bian2==n-1&&ans2==ans)            {                flag=1;break;            }        }        if(flag==0)            printf("%d\n",ans);        else printf("Not Unique!\n");    }    return 0;}


0 0