poj 1679(次小生成树)

来源:互联网 发布:风险概率影响矩阵 编辑:程序博客网 时间:2024/05/20 09:10

http://poj.org/problem?id=1679
题意:给你一个图,求最小生成树是否唯一。
思路:求次小生成树,看它和最小生成树的权值是否相等。

#include<iostream>#include<string.h>#include<stdio.h>#include<algorithm>#define INF 99999999using namespace std;int vis[10005];int f[105];int n,m;struct Edge{    int from,to,dis;}edge[10005];bool cmp(const Edge&a,const Edge&b){    return a.dis<b.dis;}int findf(int k){    if(f[k]!=k)        f[k]=findf(f[k]);    return f[k];}bool Union(int a,int b){    int fa=findf(a);    int fb=findf(b);    if(fa!=fb)    {        f[fa]=fb;        return true;    }    return false;}int main(){    int t;    cin>>t;    while(t--)    {        scanf("%d%d",&n,&m);        for(int i=0;i<m;i++)        {            scanf("%d%d%d",&edge[i].from,&edge[i].to,&edge[i].dis);        }        sort(edge,edge+m,cmp);        int mst=0;        memset(vis,0,sizeof(vis));        for(int i=1;i<=n;i++)f[i]=i;        for(int i=0;i<m;i++)        {            if(Union(edge[i].from,edge[i].to))            {                mst+=edge[i].dis;                vis[i]=1;            }        }        ///求最小生成树,用过的边vis标记为1.        int ans=INF;        for(int i=0;i<m;i++)         {            ///依次删去每条边,删去的边vis为2。            ///再求一次最小生成树,求出最小的树就是次小生成树。            int cnt=0;            if(vis[i])            {                vis[i]=2;                int k=0;                for(int j=1;j<=n;j++)f[j]=j;                for(int j=0;j<m;j++)                {                    if(vis[j]==2)continue;                    if(Union(edge[j].from,edge[j].to))                    {                        k+=edge[j].dis;                        cnt++;                    }                }                //cout<<k<<endl;                if(cnt==n-1)                    ans=min(k,ans);                vis[i]=1;            }        }        if(ans==mst)            cout<<"Not Unique!"<<endl;        else           cout<<mst<<endl;    }}
原创粉丝点击