zoukankan      html  css  js  c++  java
  • poj1679 The Unique MST ——判断最小生成树是否唯一_kruscal算法

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

    题目大意:

      判断一个连通的无向图的最小生成树是不是唯一的,如果唯一,输出最小生成树的权值,否者输出“Not Unique!”

    题目思路:

      这题目看的书上的,其实,最开始我的想法是,在求最小生成树的过程中,如果扩展到某一个点的时候,有多种选择,也就是说,有多个权值相同的边可以选择,那么就break掉,说明最小生成树不唯一。其实这是有问题的,因为,很可能在这权值相同的边当中,只能选择其中一条,如果选择其它的就得不到最小生成树,这就是一个反例。所以原来的做法是错误的。

      书上的做法是,首先,预处理,看每个边是不是有别的边的权值和它一样的,有的话就标记一下,用结构体里面的equal表示,然后用kruscal算法求一遍最小生成树,并且把这棵最小生成树里面的边都标记一下,用结构体里面的used表示,然后,对于那种有其他边和它权值相同的那种边,同时这条边在第一次求的最小生成树里面,我们就把它删除,做法就是用结构体里面的del标记,然后再次求一遍最小生成树,不用del被标记的边,这样如果求出来的最小生成树的权值和原来的一样,说明最小生成树不唯一,break;

      然后就OK了,唉,其实这是很自然的一个想法~

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstdlib>
      4 #include <cstring>
      5 #include <cctype>
      6 #include <stack>
      7 #include <queue>
      8 #include <map>
      9 #include <set>
     10 #include <vector>
     11 #include <cmath>
     12 #include <algorithm>
     13 #define lson l, m, rt<<1
     14 #define rson m+1, r, rt<<1|1
     15 using namespace std;
     16 typedef long long int LL;
     17 const int MAXN =  0x3f3f3f3f;
     18 const int  MIN =  -0x3f3f3f3f;
     19 const double eps = 1e-9;
     20 const int dir[8][2] = {{0,1},{1,0},{0,-1},{-1,0},{-1,1},
     21   {1,1},{1,-1},{-1,-1}};
     22 const int MAX = 100+10;
     23 typedef struct Edge {
     24   int u, v, w, equal, used, del;
     25   bool operator < (const Edge &other) const {
     26     return w < other.w;
     27     //别把排序搞反了!!呵呵
     28   }
     29 }Edge;
     30 Edge edge[6000];
     31 int parent[MAX], n,m;
     32 bool first;
     33 void init() {
     34   for (int i = 1; i <= n; ++i) parent[i]= -1;
     35 }
     36 int Find(int x) {
     37   int s;
     38   for (s = x; parent[s] >= 0; s = parent[s]) ;
     39   while ( s != x) {
     40     int tmp = parent[x]; parent[x]= s; x = tmp;
     41   }
     42   return s;
     43 }
     44 void Union(int R1, int R2) {
     45   int r1 = Find(R1), r2 = Find(R2), tmp = parent[r1] + parent[r2];
     46   if (parent[r1] > parent[r2]) {
     47     parent[r1] = r2; parent[r2] = tmp;
     48   } else {
     49     parent[r2] = r1; parent[r1] = tmp;
     50   }
     51 }
     52 int kruscal() {
     53   int sum = 0, num = 0;
     54   int u, v, i, j; 
     55   init();
     56   for (i = 1; i<=m; ++i) {
     57     if (edge[i].del == 1) continue;
     58     u = edge[i].u; v = edge[i].v;
     59     if (Find(u) != Find(v)) {
     60       sum += edge[i].w; Union(u, v); num++;
     61       if (first == true) edge[i].used = 1;
     62     }
     63     if (num >= n - 1) break;
     64   }
     65   return sum;
     66 }
     67 int main(void){
     68 #ifndef ONLINE_JUDGE
     69   freopen("poj1679.in", "r", stdin);
     70 #endif
     71   int u, v, w, i, j, k, t;
     72   scanf("%d", &t); 
     73   while (t--) {
     74     scanf("%d%d", &n, &m);
     75     edge[0].w=0;
     76     for (j = 1; j <= m; ++j) {
     77       scanf("%d%d%d", &u, &v, &w);
     78       edge[j].u = u; edge[j].v = v; edge[j].w = w;
     79       edge[j].equal = edge[j].del = edge[j].used = 0;
     80     }
     81     for (j = 1; j <= m; ++j) {
     82       for (k = j+1; k <= m; ++k) {
     83         if (edge[k].w == edge[j].w) edge[j].equal=edge[k].equal= 1;
     84       }
     85     }
     86     sort(edge + 1, edge + m + 1);
     87     first = true; 
     88     int weight1 = kruscal(), weight2;
     89     first = false;
     90     for (j = 1; j <= m; ++j) {
     91       if (edge[j].used && edge[j].equal) {
     92         edge[j].del = 1; weight2 = kruscal();
     93         if (weight2 == weight1) {
     94           printf("Not Unique!\n"); break;
     95         }
     96         edge[j].del = 0;
     97       }
     98     }
     99     if (j > m) printf("%d\n", weight1);
    100   }
    101 
    102   return 0;
    103 }

      写的过程中,出现了一个错误,导致开始运行怎么也不对,就是结构体里面的运算符重载小于号写反了……因为要从小到大排序,所以都写成小于号。

  • 相关阅读:
    计算两个latitude-longitude点之间的距离? (Haversine公式)
    Spring Boot工程支持HTTP和HTTPS,HTTP重定向HTTPS
    Invalid character found in method name. HTTP method names must be tokens
    Http压测工具wrk使用指南
    Android自定义带下划线EditText解决文字压线的问题
    Android-PullToRefresh 使用心得
    GridView 和ListView中自适应高度
    【Android多屏适配】动态改变Listview item高度
    Android listview的item设定高度
    Android ListView高度自适应和ScrollView冲突解决
  • 原文地址:https://www.cnblogs.com/liuxueyang/p/3060228.html
Copyright © 2011-2022 走看看