zoukankan      html  css  js  c++  java
  • ACM/ICPC 之 判别MST唯一性-Kruskal解法(POJ1679)

    判别MST是否唯一的例题。


    POJ1679-The Unique MST

     

      题意:给定图,求MST(最小生成树)是否唯一,唯一输出路径长,否则输出Not Unique!

      题解:MST是否唯一取决于是否有两边权值相同(其中一条边在第一次求得的MST内,另一条在MST外)的情况。

         如果存在这样的边,则需要逐次删除MST内的该边,再次求MST,如果此次求得的MST路长与第一次MST相同,则确实存在不唯一的MST

         否则,一定不存在多条MST。

      1 //Kruskal-判断MST是否唯一
      2 //Time:0MS    Memory:868K
      3 #include<iostream>
      4 #include<cstring>
      5 #include<cstdio>
      6 #include<algorithm>
      7 using namespace std;
      8 
      9 #define MAX 101
     10 
     11 struct Edge {
     12     int u, v;
     13     int w;
     14     bool used;    //First Used
     15     bool del;    //Kruskal是否不考虑此边
     16     friend bool operator < (Edge e1, Edge e2) { return e1.w < e2.w; }
     17 }e[MAX*MAX];
     18 
     19 int n, m;
     20 bool first;    //是否第一次求MST
     21 int fa[MAX];
     22 int del[MAX*MAX], len;    //须逐次删除的边
     23 int minroad;    //第一次MST结果
     24 
     25 int Find(int x)
     26 {
     27     return fa[x] < 0 ? x : fa[x] = Find(fa[x]);
     28 }
     29 
     30 void Union(int r1, int r2)
     31 {
     32     r1 = Find(r1);
     33     r2 = Find(r2);
     34     int num = fa[r1] + fa[r2];
     35     if (fa[r1] < fa[r2])
     36     {
     37         fa[r2] = r1;
     38         fa[r1] = num;
     39     }
     40     else {
     41         fa[r1] = r2;
     42         fa[r2] = num;
     43     }
     44 }
     45 
     46 bool kruskal()
     47 {
     48     memset(fa, -1, sizeof(fa));
     49     int num = 0;
     50     int mind = 0;
     51     for (int i = 0; i < m; i++)
     52     {
     53         if (e[i].del)    continue;
     54         if (Find(e[i].u) == Find(e[i].v))    continue;
     55         Union(e[i].u, e[i].v);
     56         if (first) {
     57             minroad += e[i].w;
     58             e[i].used = true;
     59         }
     60         mind += e[i].w;
     61         if (mind > minroad) return true;
     62         if (++num == n - 1) break;
     63     }
     64     
     65     return false;
     66 }
     67 
     68 int main()
     69 {
     70     int T;
     71     scanf("%d", &T);
     72     while (T--)
     73     {
     74         scanf("%d%d", &n, &m);
     75         memset(e, 0, sizeof(e));
     76         for (int i = 0; i < m; i++)
     77             scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].w);
     78 
     79         len = 0;
     80         sort(e, e + m);
     81         for (int i = 0; i < m; i++)
     82             if (e[i].w == e[i + 1].w)
     83             {
     84                 if(del[len-1] != i) del[len++] = i;
     85                 del[len++] = i + 1;
     86             }
     87         
     88         minroad = 0;
     89         first = true;
     90         kruskal();
     91         first = false;
     92 
     93         bool unique = true;
     94         for (int i = 0; i < len; i++)
     95         {
     96             if (!e[del[i]].used) continue;    //使用过的才删除
     97             e[del[i]].del = true;    //删除
     98             if (!kruskal())
     99             {
    100                 printf("Not Unique!
    ");
    101                 unique = false; break;
    102             }
    103             e[del[i]].del = false;    //恢复
    104         }
    105 
    106         if (unique)
    107             printf("%d
    ", minroad);
    108     }
    109 
    110 
    111 
    112     return 0;
    113 }
    他坐在湖边,望向天空,她坐在对岸,盯着湖面
  • 相关阅读:
    ES6中的export,import ,export default
    centos7 安装php 多线程pthreads
    ubuntu系统安装nginx出现的错误(依赖环境没有安装完)
    ubuntu彻底干净卸载MySQL、Apache2、Php的方法(各版本通用
    mysql-ubuntu14.04彻底卸载mysql
    centos 中GTK的安装
    centos 安装cmake 3.3.2
    yum安装方式的php,切换NTS为ZTS版本
    eclipse中jad反编译工具的安装
    在SpringMVC中获取request对象的几种方式
  • 原文地址:https://www.cnblogs.com/Inkblots/p/5390767.html
Copyright © 2011-2022 走看看