`

POJ1679 The Unique MST

    博客分类:
  • MST
阅读更多

题意:判断最小生成树是否唯一

思路:第一次用kruskal求出最小生成树,记为ans,然后依次去除已经选进来的边,进行kruskal,如果ans==kruskal()的话,则输出不唯一。

注意:1.第一次求kruskal时记得要先判断是否能生成最小生成树(但是我没判断就A了。。理论上来说是要判断的。。)

2.注意存放变的数组开大一点。我用G++交了几次一直WA,原代码改成C++交就RE,然后数组改了下大小就A了。被G++坑死了。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <stack>
#include <map>
#include <iomanip>
#define PI acos(-1.0)
#define Max 20005
#define inf 1<<28
using namespace std;

struct kdq
{
    int s,e,l;
} road[Max];
int f[Max];
bool visit[Max];
bool visit1[Max];
int n,m;

bool cmp(kdq x,kdq y )
{
    return x.l<y.l;
}

int find(int x)
{
    return f[x]==x?x:f[x]=find(f[x]);
}

void Union(int x,int y)
{
    x=find(x);
    y=find(y);
    if(x==y)return ;
    if(y>x)
        f[y]=x;
    else
        f[x]=y;
}

int kruskal(int d)//d是用来删除边的
{
    int num=0;
    int num1=0;
    for(int i=0; i<m; i++)
    {
        if(i!=d)
        {
            int x=find(road[i].s);
            int y=find(road[i].e);
            if(y!=x)
            {
                num1++;
                Union(x,y);
                num+=road[i].l;
                visit[i]=1;//记录第一次取来的边的标号
            }
        }
    }
    if(num1==n-1)//判断能生成最小生成树
    return num;
    else
    return -1;
}

int main()
{
    int i,j,k,l,T;
    cin>>T;
    while(T--)
    {
        memset(visit,0,sizeof(visit));
        cin>>n>>m;
        for(i=0; i<=n; i++)
            f[i]=i;
        for(i=0; i<m; i++)
            scanf("%d%d%d",&road[i].s,&road[i].e,&road[i].l);
        sort(road,road+m,cmp);
        int ans=kruskal(-1);
        for(i=0; i<m; i++)
            visit1[i]=visit[i];//将第一标记的序号存入visit1[],因为visit[]在接下来的kruskal中还会改变
        if(ans==-1)//这个判断不需要也可以过。。难道是数据水了?
        {
            cout<<0<<endl;
            continue;
        }
        bool flag=0;
        for(i=0; i<m; i++)
        {
            if(visit1[i])//如果是第一次取到的边
            {
                for(j=0; j<=n; j++)
                    f[j]=j;
                if(kruskal(i)==ans)//如果删除了这条边后,最小生成树的值相等,则说明不唯一
                {
                    flag=1;
                    break;
                }
            }
        }
        if(flag)
            cout<<"Not Unique!"<<endl;
        else
            cout<<ans<<endl;
    }
    return 0;
}


更多详细信息请查看java教程网 http://www.itchm.com/forum-59-1.html
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics