poj1679(最小生成树)

给定一个图,询问是否存在不同的最小生成树
思路:先用kru或者prim跑一条最小生成树,把最小生成树里面的边存起来,然后每次删除一条边跑最小生成树算法,看跑出来的生成树和之前的是否一样,如果一样就有不同的最小生成树,否则就没有
注意:边权为0的边视为图任然联通,但是删除这条边时就不用和原来的比较(因为跑出来的树如果和原来的相等,就代表又来了一个0权边,不能算作和原来的不一样)

#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#include<time.h>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<functional>
#include<stack>
#include<map>
#include<queue>
#define mod (1000000007)
#define middle (l+r)>>1
#define SIZE 10000+10
//#define lowbit(x) (x&(-x))
#define lson (rt<<1)
#define rson (rt<<1|1)
typedef long long ll;
const int inf_max = 0x3f3f3f3f;
const ll Linf = 9e18;
const int maxn = 100+10;
const double eps=0.0001;
using namespace std;
int n,m,cnt,first,another,father[maxn],vis[maxn*maxn];
bool flag;
struct Edge
{
    int u,v,val;
    bool operator<(const Edge e)const
    {
        return val<e.val;
    }
}edge[maxn*maxn];
vector<int>v;
void Initial()
{
    for(int i=1;i<=110;i++)
        father[i]=i;
    first=0;another=0;
    memset(edge,0,sizeof(edge));
    memset(vis,0,sizeof(vis));   //边是否被删去
    flag=false;
    v.clear();
}
int Find(int x)
{
    if(father[x]==x)
        return father[x];
    return father[x]=Find(father[x]);
}
void Kru(bool f)
{
    int c=1;
    another=0;
    for(int i=1;i<=m;i++)
    {
        if(vis[i])
            continue;
        //printf("i=%d,c=%d,u=%d,v=%d,val=%d\n",i,c,edge[i].u,edge[i].v,edge[i].val);
        int fu=Find(edge[i].u),fv=Find(edge[i].v);
        if(fu!=fv)
        {
            if(!f)
                v.push_back(i);
            if(!f)
                first+=edge[i].val;
            else
            {
                another+=edge[i].val;
                //printf("i=%d,anopther=%d,val=%d\n",i,another,edge[i].val);
            }
            father[fu]=fv;
            c++;
        }
        if(c==n)
            break;
    }
    if(!f&&c!=n)
        first=0;
    if(f)
    {
        if(another==first)
        {
            //printf("first=%d,another=%d\n",first,another);
            flag=true;
        }
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        Initial();
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            int u,v,val;
            scanf("%d%d%d",&u,&v,&val);
            edge[i].u=u;
            edge[i].v=v;
            edge[i].val=val;
        }
        sort(edge+1,edge+1+m);
        Kru(0);
//        printf("%d\n",first);
//        for(int i=0;i<v.size();i++)
//            printf("%d  ",v[i]);
//        printf("\n");
        for(int i=0;i<v.size();i++)
        {
            if(edge[i].val==0)
                continue;
            for(int i=1;i<=110;i++)
                father[i]=i;
            vis[v[i]]=1;
            Kru(1);
            vis[v[i]]=0;
        }
        if(flag)
            printf("Not Unique!\n");
        else
            printf("%d\n",first);
    }
    return 0;
}

发布了33 篇原创文章 · 获赞 14 · 访问量 437

猜你喜欢

转载自blog.csdn.net/qq_44077455/article/details/102886086