您的位置:首页 > 产品设计 > UI/UE

poj 1679 The Unique MST(次小生成树)

2015-04-21 00:49 323 查看
题目链接:题目链接

判断一个无向连通图的最小生成树是否唯一

借用次小生成树来判断

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string.h>
#include <string>
#include <vector>
#include <queue>

#define MEM(a,x) memset(a,x,sizeof a)
#define eps 1e-8
#define MOD 10009
#define MAXN 110
#define MAXM 100010
#define INF 99999999
#define ll __int64
#define bug cout<<"here"<<endl
#define fread freopen("ceshi.txt","r",stdin)
#define fwrite freopen("out.txt","w",stdout)

using namespace std;

int Read()
{
    char ch;
    int a = 0;
    while((ch = getchar()) == ' ' | ch == '\n');
    a += ch - '0';
    while((ch = getchar()) != ' ' && ch != '\n')
    {
        a *= 10;
        a += ch - '0';
    }
    return a;
}

void Print(int a)
{
     if(a>9)
         Print(a/10);
     putchar(a%10+'0');
}
bool vis[MAXN];
int lowc[MAXN];
int pre[MAXN];
int Max[MAXN][MAXN];//Max[i][j]表示在最小生成树中从i到j的路径中的最大边权
bool used[MAXN][MAXN];
int Prim(int cost[][MAXN],int n)
{
    int ans=0;
    MEM(vis,0);
    MEM(Max,0);
    MEM(used,0);
    vis[0]=1;
    pre[0]=-1;
    for(int i=1;i<n;i++)
    {
        lowc[i]=cost[0][i];
        pre[i]=0;
    }
    lowc[0]=0;
    for(int i=1;i<n;i++)
    {
        int minc=INF;
        int p=-1;
        for(int j=0;j<n;j++)
            if(!vis[j]&&minc>lowc[j])
        {
            minc=lowc[j]; p=j;
        }
        if(minc==INF) return -1;
        ans+=minc;
        vis[p]=1;
        used[p][pre[p]]=used[pre[p]][p]=1;
        for(int j=0;j<n;j++)
        {
            if(vis[j])
                Max[j][p]=Max[p][j]=max(Max[j][pre[p]],lowc[p]);
            if(!vis[j]&&lowc[j]>cost[p][j])
            {
                lowc[j]=cost[p][j];
                pre[j]=p;
            }
        }
    }
    return ans;
}
int ans;
int smst(int cost[][MAXN],int n)
{
    int Min=INF;
    for(int i=0;i<n;i++)
        for(int j=i+1;j<n;j++)
            if(cost[i][j]!=INF&&!used[i][j])
            {
                Min=min(Min,ans+cost[i][j]-Max[i][j]);
            }
    if(Min==INF) return -1;
    return Min;
}
int cost[MAXN][MAXN];

int main()
{
//    fread;
    int tc;
    scanf("%d",&tc);
    while(tc--)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
        {
            if(i==j) cost[i][j]=0;
            else cost[i][j]=INF;
        }
        while(m--)
        {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            u--; v--;
            cost[u][v]=cost[v][u]=w;
        }
        ans=Prim(cost,n);
        if(ans==-1)
        {
            puts("Not Unique!");
            continue;
        }
        int res=smst(cost,n);
        if(ans==res)
            puts("Not Unique!");
        else printf("%d\n",ans);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: