POJ 1679The Unique MST (判断MST是否唯一、次小生成树)

 

Definition 1 (Spanning Tree): Consider a connected, undirected graph G = (V, E). A spanning tree of G is a subgraph of G, say T = (V', E'), with the following properties:
1. V' = V.
2. T is connected and acyclic.

Definition 2 (Minimum Spanning Tree): Consider an edge-weighted, connected, undirected graph G = (V, E). The minimum spanning tree T = (V, E') of G is the spanning tree that has the smallest total cost. The total cost of T means the sum of the weights on all the edges in E'.

#include <cstdio>
#include <algorithm>
//经过简单修改,可以变成求次小生成树的代码 ,但是复杂度较高
using namespace std;
const int maxn=105;
const int maxm=10005;
int p[maxn],n,m;
bool is_uni;

struct edge
{
    int u,v,w;
    bool eql,used,del;
}e[maxm];

inline void init (const int &x) {p[x]=-1;}

int find (int x)
{
    return p[x]>=0?p[x]=find(p[x]):x;
}
 
bool cmp(edge a,edge b)
{
    return a.w<b.w;
}

int kruskal ()
{
    //printf("MST:\n");
    int i,ans=0;
    for (i=0 ; i<=n ; ++i)init(i);
    sort(e,e+m,cmp);
    for (i=0 ; i<m ; ++i)
    if(!e[i].del)
    {
        int s=find(e[i].u),t=find(e[i].v);
        if(s!=t)
        {
            ans+=e[i].w;
            int tmp=p[s]+p[t];
            p[s]>p[t]?(p[s]=t,p[t]=tmp):(p[t]=s,p[s]=tmp);
            if(!is_uni)e[i].used=true;//只标记第一次生成的树的边
            //printf("%d %d %d\n",e[i].u,e[i].v,e[i].w);
        }
    }
    //printf("%d\n",ans);
    return ans;
}

int main ()
{
    int i,j;
    int cas,ans,ans2;
    scanf("%d",&cas);
    while (cas--)
    {
        scanf("%d%d",&n,&m);
        for (i=0 ; i<m ; ++i)
        {
            scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
            e[i].eql=e[i].used=e[i].del=false;
        }
        for (i=0 ; i<m ; ++i)
          if(!e[i].eql)
            for (j=i+1 ; j<m ; ++j)
              if(e[i].w==e[j].w)e[i].eql=e[j].eql=true;
        is_uni=false;
        ans=kruskal();
        is_uni=true;
        for (i=0 ; i<m ; ++i)
        {
            if(e[i].eql==true && e[i].used==true)
            {
                e[i].del= true;
                ans2=kruskal();
                if(ans==ans2){is_uni=false;break;}
                else e[i].del=false;
            }
        }
        if(is_uni)printf("%d\n",ans);
        else printf("Not Unique!\n");
    }
    return 0;
}

 

你可能感兴趣的:(POJ 1679The Unique MST (判断MST是否唯一、次小生成树))