poj1679唯一最小生成树

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <climits>
#include <string>
#include <iostream>
#include <map>
#include <cstdlib>
#include <list>
#include <set>
#include <queue>
#include <stack>

using namespace std;
const int maxn=105;
int father[maxn];

int getfather(int x)
{
    if(x!=father[x])
        father[x]=getfather(father[x]);
    return father[x];
}
struct Node
{
    int a;int b;int c;
}node[maxn*maxn];

int cmp(const Node &a,const Node &b)
{
    return a.c<b.c;
}
int gg[maxn];
int vis[maxn];
int main()
{
    int Icase;int n,m;
    while(cin>>Icase){
        while(Icase--){
            cin>>n>>m;
            for(int i=1;i<=n;i++)father[i]=i;
            for(int i=0;i<m;i++){
                int a,b,c;cin>>a>>b>>c;
                node[i].a=a;node[i].b=b;node[i].c=c;
            }
            sort(node,node+n,cmp);int ans=0;
            int sum=0;
            for(int i=0;i<m;i++){
                int fa=getfather(node[i].a);int fb=getfather(node[i].b);int c=node[i].c;
                if(fa!=fb){
                    gg[ans++]=i;sum+=c;father[fa]=fb;
                }
            }
            int ret=0;
            memset(vis,0,sizeof(vis));
            for(int i=0;i<ans;i++){
                vis[gg[i]]=1; int ans1=0;int sum1=0;
                for(int j=1;j<=n;j++) father[j]=j;
                for(int j=0;j<m;j++){
                    if(!vis[j]){
                        int fa=getfather(node[j].a);int fb=getfather(node[j].b);int c=node[j].c;
                        if(fa!=fb){
                            sum1+=c;father[fa]=fb;
                        }
                    }
                }
                for(int j=1;j<=n;j++){
                    if(father[j]==j) ans1++;
                }
             //   cout<<ans1<<" "<<sum1<<endl;system("pause");
                if(ans1==1) if(sum1==sum) ret++;
                vis[gg[i]]=0;
            }
            if(ret>0) cout<<"Not Unique!"<<endl;
            else cout<<sum<<endl;
        }
    }
    return 0;
}

poj1679唯一最小生成树

时间: 2024-10-05 23:27:04

poj1679唯一最小生成树的相关文章

poj1679(最小生成树)

传送门:The Unique MST 题意:判断最小生成树是否唯一. 分析:先求出原图的最小生成树,然后枚举删掉最小生成树的边,重做kruskal,看新的值和原值是否一样,一样的话最小生成树不唯一. #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<queue> #include<v

离散数学:每条边的权重均不相同的带权图有唯一最小生成树

假设存在两个最小生成树T,T',其边按权重升序排列分别为{e1, e2, ..., en}和{e1', e2', ..., en'}. 那么存在一个最小的k使得weight(ek)!=weight(ek').(也即e1=e1', e2=e2', ... ek-1=ek-1') 此时T'中没有ek.不妨设w(ek)<w(ek'),则T'+ek里必然会有一个环,而且这个环有除了{e1', e2', ..., en'}之外的边(否则在T中就会有这样的环).删去任一这样的边,即可得到一个更小的生成树,这

[Tvvj1391]走廊泼水节(最小生成树)

[Tvvj1391]走廊泼水节 Description 给定一棵N个节点的树,要求增加若干条边,把这棵树扩充为完全图,并满足图的唯一最小生成树仍然是这棵树.求增加的边的权值总和最小是多少. 完全图:完全图是一个简单的无向图,其中每对不同的顶点之间都恰连有一条边相连(来自百度百科) 输入格式 本题为多组数据 第一行t,表示有t组测试数据 对于每组数据 第一行N,表示水龙头的个数(当然也是OIER的个数): 2到N行,每行三个整数X,Y,Z:表示水龙头X和水龙头Y有一条长度为Z的小道 输出格式 对于

Contest Hunter CH6201 走廊泼水节 最小生成树 Kruskal

$ \rightarrow $ 戳我进CH原题 走廊泼水节 0x60「图论」例题 总时限10 s $ \quad $ 总内存256 MiB 描述 [简化版题意]给定一棵N个节点的树,要求增加若干条边,把这棵树扩充为完全图,并满足图的唯一最小生成树仍然是这棵树. 求增加的边的权值总和最小是多少. 我们一共有 $ N $ 个OIER打算参加这个泼水节,同时很凑巧的是正好有 $ N $ 个水龙头(至于为什么,我不解释). $ N $ 个水龙头之间正好有 $ N-1 $ 条小道,并且每个水龙头都可以经过

CH6201 走廊泼水节【最小生成树】

6201 走廊泼水节 0x60「图论」例题 描述 [简化版题意]给定一棵N个节点的树,要求增加若干条边,把这棵树扩充为完全图,并满足图的唯一最小生成树仍然是这棵树.求增加的边的权值总和最小是多少. 我们一共有N个OIER打算参加这个泼水节,同时很凑巧的是正好有N个水龙头(至于为什么,我不解释).N个水龙头之间正好有N-1条小道,并且每个水龙头都可以经过小道到达其他水龙头(这是一棵树,你应该懂的..).但是OIER门为了迎接中中的挑战,决定修建一些个道路(至于怎么修,秘密~),使得每个水龙头到每个

最小生成树——克鲁斯克算法+一道例题

//最小生成树,Kruskal算法 struct rec { int x; int y; int z; }edge[50010]; int fa[10010],n,m,ans; bool operator <(rec a,rec b) { return a.z<b.z; } int get(int x) { if(x==fa[x]) return x; return fa[x]=get(fa[x]); //压缩路径,构造并查集 } int main() { cin>>n>&g

poj图论解题报告索引

最短路径: poj1125 - Stockbroker Grapevine(多源最短路径,floyd) poj1502 - MPI Maelstrom(单源最短路径,dijkstra,bellman-ford,spfa) poj1511 - Invitation Cards(单源来回最短路径,spfa邻接表) poj1797 - Heavy Transportation(最大边,最短路变形,dijkstra,spfa,bellman-ford) poj2240 - Arbitrage(汇率问题,

杭州的培训Day2考试

简单来说就是完了 思路都对了 就是写不出来 浪费了三个小时来做第一题 还是没有过 然而第三题也没有做对 第二题没空做 这样就... 报零了! 然后第一题: 1.分糖果   (candy.pas/c/cpp) [问题描述] 幼儿园的小朋友要吃糖果,正在幼儿园帮忙的小x接到了这个任务,当然,这个任务不是那么简单. 现在有n名小朋友,m颗糖果,每个小朋友对糖果的需求都不一样,如果知道第i个小朋友需要x[i]颗糖,但是小x必须分给第i个小朋友y[i]颗糖,老师就认为小朋友的不高兴指数为|x[i]/v-y

【次小生成树】【Kruskal】【prim】【转】

原博客出处:https://blog.csdn.net/yasola/article/details/74276255 通常次小生成树是使用Prim算法进行实现的,因为可以在Prim算法松弛的同时求得最小生成树上任意两点之间的最长边.但是利用Kruskal算法却没办法在松弛的同时求得. 所以我们就要在Kruskal求完最短路后,对于每个顶点bfs一次,得到树上任意两点的最长边.之后求可以像之前一样枚举不在树上的边,代替找最小值了. 两种方法的时间杂度是一样的,但Kruskal的实现代码回长非常多