POJ1679The Unique MST(次小生成树)

The Unique MST

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 25203   Accepted: 8995

Description

Given a connected undirected graph, tell if its minimum spanning tree is unique.

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‘.

Input

The first line contains a single integer t (1 <= t <= 20), the number of test cases. Each case represents a graph. It begins with a line containing two integers n and m (1 <= n <= 100), the number of nodes and edges. Each of the following m lines contains a triple (xi, yi, wi), indicating that xi and yi are connected by an edge with weight = wi. For any two nodes, there is at most one edge connecting them.

Output

For each input, if the MST is unique, print the total cost of it, or otherwise print the string ‘Not Unique!‘.

Sample Input

2
3 3
1 2 1
2 3 2
3 1 3
4 4
1 2 2
2 3 2
3 4 2
4 1 2

Sample Output

3
Not Unique!

题意:问一棵最小生成树是否唯一找次小生成树,如果相等不唯一,否则唯一

次小生成树:就是最小生成树换一条边而成的生成树;用maxd【x】【y】存储最小生成树两个节点(x,y)路径中最大的那条边的权值,也就是最小生成树中x-z-...-y中那个最大的那一个权值,然后就可以换边了,到底换哪一个边就从不在生成树中的边一个一个枚举咯,假设x-y,如果要用x-y替换x-z...-y肯定得替换x-z...-y中权值最大的那条边才能让最后得到结果只比x-z...-y小一点,也就是仅次于

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <algorithm>
  4 #include <cstring>
  5 using namespace std;
  6 const int MAX = 110;
  7 const int INF = 100000000;
  8 int n,m,ans,cnt;
  9 int edge[MAX][MAX],vis[MAX],used[MAX][MAX],dist[MAX];
 10 int pre[MAX],maxd[MAX][MAX];
 11 void prime()
 12 {
 13     memset(vis,0,sizeof(vis));
 14     memset(used,false,sizeof(used));
 15     memset(maxd,0,sizeof(maxd));
 16     for(int i = 1; i <= n; i++)
 17     {
 18         dist[i] = edge[1][i];
 19         pre[i] = 1;
 20     }
 21     vis[1] = 1;
 22     pre[1] = -1;
 23     for(int i = 1; i < n; i++)
 24     {
 25         int minn = INF,pos;
 26         for(int j = 1; j <= n; j++)
 27         {
 28             if(vis[j] == 0 && dist[j] < minn)
 29             {
 30                 minn = dist[j];
 31                 pos = j;
 32             }
 33         }
 34         if(minn == INF)
 35         {
 36             ans = INF;
 37             return;
 38         }
 39         ans += minn;
 40         vis[pos] = 1;
 41         used[pos][pre[pos]] = used[ pre[pos] ][pos] = true;
 42         for(int j = 1; j <= n; j++)
 43         {
 44             if(vis[j])
 45                 maxd[j][pos] = maxd[pos][j] = max(dist[pos], maxd[j][pre[pos]]);
 46             if(vis[j] == 0 && dist[j] > edge[pos][j])
 47             {
 48                 dist[j] = edge[pos][j];
 49                 pre[j] = pos;
 50             }
 51         }
 52     }
 53 }
 54 void smst()
 55 {
 56     cnt = INF;
 57     for(int i = 1; i <= n; i++)
 58     {
 59         for(int j = i + 1; j <= n; j++)
 60         {
 61             if(used[i][j] == false && edge[i][j] != INF)
 62             {
 63                 cnt = min(cnt, ans - maxd[i][j] + edge[i][j]);
 64             }
 65         }
 66     }
 67 }
 68 int main()
 69 {
 70     int t;
 71     scanf("%d", &t);
 72     while(t--)
 73     {
 74         for(int i = 1; i <= n; i++)
 75             for(int j = i + 1; j <= n; j++)
 76             {
 77                 edge[i][i] = 0;
 78                 edge[i][j] = edge[j][i] = INF;
 79             }
 80         scanf("%d%d", &n,&m);
 81         for(int i = 0; i < m; i++)
 82         {
 83             int x,y,w;
 84             scanf("%d%d%d", &x, &y, &w);
 85             edge[x][y] = edge[y][x] = w;
 86         }
 87         ans = 0;
 88         prime();
 89         smst();
 90         if(ans == INF)
 91         {
 92             printf("Not Unique!\n");
 93             continue;
 94         }
 95         if(cnt == ans)
 96         {
 97             printf("Not Unique!\n");
 98         }
 99         else
100         {
101             printf("%d\n",ans);
102         }
103     }
104     return 0;
105 }

				
时间: 2024-10-08 23:05:13

POJ1679The Unique MST(次小生成树)的相关文章

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

The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 20293   Accepted: 7124 Description Given a connected undirected graph, tell if its minimum spanning tree is unique. Definition 1 (Spanning Tree): Consider a connected, undire

POJ_1679_The Unique MST(次小生成树模板)

The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 23942   Accepted: 8492 Description Given a connected undirected graph, tell if its minimum spanning tree is unique. Definition 1 (Spanning Tree): Consider a connected, undire

hdu 1679 The Unique MST 次小生成树 简单题

The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 21737   Accepted: 7692 Description Given a connected undirected graph, tell if its minimum spanning tree is unique. Definition 1 (Spanning Tree): Consider a connected, undire

[POJ1679]The Unique MST 次小生成树

题目链接:http://poj.org/problem?id=1679 给你一个图的连通情况,询问你此图的最小生成树是否唯一. 假如最小生成树唯一,即生成树连通所有节点的权值和唯一.假如不唯一,那么存在另一条最小生成树使得权值等于之前最小生成树的权值. 换个思路考虑,也就是次小生成树的权值与最小生成树的权值相同,那么问题就变成了求次小生成树的权值. 我选择的是先求出最小生成树,将树上用到的边都保存下来.接着分别将每一条用到的边摘下来,再求一次最小生成树.假如不包含当前删掉的边生成的生成树的所选边

poj 1679 The Unique MST (次小生成树(sec_mst)【kruskal】)

The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 35999   Accepted: 13145 Description Given a connected undirected graph, tell if its minimum spanning tree is unique. Definition 1 (Spanning Tree): Consider a connected, undir

POJ - 1679 The Unique MST(次小生成树)

版权声明:本文为博主原创文章,未经博主允许不得转载.

POJ--1679--The Unique MST【kruskal判断MST是否唯一】

链接:http://poj.org/problem?id=1679 题意:告诉你有n个点,m条边,以及m条边的信息(起点.终点.权值),判断最小生成树是否唯一 判断MST是否唯一的思路是这样:对于每条边如果有和他相等权值的边,则做一个标记,然后进行一遍kruskal或prim找出最小生成树权值,然后对于每个使用过并且有相等边标记的边,把它从图中删去,再进行一遍kruskal或prim,如果此时最小生成树权值和第一次一样,则说明最小生成树不唯一,否则最小生成树唯一. #include<cstrin

poj1679The Unique MST判断最小生成树是否唯一以及求次小生成树边权和的讲解

Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 22346   Accepted: 7924 Description Given a connected undirected graph, tell if its minimum spanning tree is unique. Definition 1 (Spanning Tree): Consider a connected, undirected graph G =

POJ--1679--The Unique MST【推断MST是否唯一】

链接:http://poj.org/problem? id=1679 题意:告诉你有n个点,m条边,以及m条边的信息(起点.终点.权值).推断最小生成树是否唯一 之前是用另外一种方法做的.复杂度最高可达O(n^3),后来用次小生成树又做了一次.复杂度O(n^2+m). 先说次小生成树的方法. 次小生成树:求出最小生成树,把用到的边做标记,此时加入额外的边进去必定形成环,删除环中第二大的边(即这个环里在生成树上的最大边),加上额外边的权值,枚举每一个额外边,取最小值,就是次小生成树的值.用同样的方