码迷,mamicode.com
首页 > 其他好文 > 详细

[POJ1679]The Unique MST 次小生成树

时间:2015-11-07 21:53:15      阅读:224      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:http://poj.org/problem?id=1679

  给你一个图的连通情况,询问你此图的最小生成树是否唯一。

  假如最小生成树唯一,即生成树连通所有节点的权值和唯一。假如不唯一,那么存在另一条最小生成树使得权值等于之前最小生成树的权值。

  换个思路考虑,也就是次小生成树的权值与最小生成树的权值相同,那么问题就变成了求次小生成树的权值。

 

  我选择的是先求出最小生成树,将树上用到的边都保存下来。接着分别将每一条用到的边摘下来,再求一次最小生成树。假如不包含当前删掉的边生成的生成树的所选边权值与最小生成树的所选边权值相同,那么最小生成树就是不唯一的了。

 

代码:

 

  1 #include <algorithm>
  2 #include <iostream>
  3 #include <iomanip>
  4 #include <cstring>
  5 #include <climits>
  6 #include <complex>
  7 #include <fstream>
  8 #include <cassert>
  9 #include <cstdio>
 10 #include <bitset>
 11 #include <vector>
 12 #include <deque>
 13 #include <queue>
 14 #include <stack>
 15 #include <ctime>
 16 #include <set>
 17 #include <map>
 18 #include <cmath>
 19 
 20 using namespace std;
 21 
 22 typedef struct Node {
 23     int u;
 24     int v;
 25     int w;
 26 }Node;
 27 
 28 bool cmp(Node n1, Node n2) {
 29     return n1.w < n2.w;
 30 }
 31 
 32 const int maxn = 111;
 33 Node node[6666];
 34 int vis[maxn];
 35 int n, m, u, v, w;
 36 int pre[maxn];
 37 int cnt, dig, flag, ans;
 38 
 39 void init() {
 40     for(int i = 0; i <= maxn; i++) {
 41         pre[i] = i;
 42     }
 43 }
 44 
 45 int find(int x) {
 46     return x == pre[x] ? x : pre[x] = find(pre[x]);
 47 }
 48 
 49 void unite(int x, int y) {
 50     x = find(x);
 51     y = find(y);
 52     if(x != y) pre[y] = x;
 53 }
 54 
 55 int main() {
 56     // freopen("in", "r", stdin);
 57     int T;
 58     scanf("%d", &T);
 59     while(T--) {
 60         init();
 61         memset(vis, 0, sizeof(vis));
 62         memset(node, 0, sizeof(node));
 63         dig = 0;
 64         cnt = 0;
 65         flag = 0;
 66         scanf("%d %d", &n, &m);
 67         for(int i = 0; i < m; i++) {
 68             scanf("%d %d %d", &u, &v, &w);
 69             node[i].u = u;
 70             node[i].v = v;
 71             node[i].w = w;
 72         }
 73         sort(node, node+m, cmp);
 74         for(int i = 0; i < m && cnt < n; i++) {
 75             if(find(node[i].u) != find(node[i].v)) {
 76                 unite(node[i].u, node[i].v);
 77                 vis[cnt++] = i;
 78                 dig += node[i].w;
 79             }
 80         }
 81         ans = dig;
 82 
 83         for(int i = 1; i < n; i++) {
 84             init();
 85             cnt = n - 1;
 86             dig = 0;
 87             for(int j = 0; j < m && cnt; j++) {
 88                 if(vis[i] != j && find(node[j].u) != find(node[j].v)) {
 89                     unite(node[j].u, node[j].v);
 90                     dig += node[j].w;
 91                     cnt--;
 92                 }
 93             }
 94             if(cnt == 0 && dig == ans) {
 95                 flag = 1;
 96                 break;
 97             }
 98         }
 99 
100         if(flag) printf("Not Unique!\n");
101         else printf("%d\n", ans);
102     }
103 }

 

[POJ1679]The Unique MST 次小生成树

标签:

原文地址:http://www.cnblogs.com/vincentX/p/4946099.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!