zoukankan      html  css  js  c++  java
  • POJ-1679 The Unique MST---判断最小生成树是否唯一

    题目链接:

    https://vjudge.net/problem/POJ-1679

    题目大意:

    给定一个无向连通网,判断最小生成树是否唯一。

    思路:

    (1)对图中的每条边,扫描其他边,如果存在相同权值的边,对该边做标记。

    (2)然后用kruskal算法或者prim算法求MST(标记MST中的边)

    (3)求得MST后,如果MST中未包含做了标记的边,那么MST唯一。

    MST中不包含未标记的边,说明MST中没有那些权值相同的边,用kruskal算法可知,该最小生成树肯定唯一。

    (4)如果包含标记的边,依次去掉这些边,再求MST,如果所求的MST权值和之前的MST权值一样说明最小生成树不唯一,反之,则唯一。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<cmath>
      6 #include<queue>
      7 #include<stack>
      8 #include<map>
      9 #include<sstream>
     10 using namespace std;
     11 typedef long long ll;
     12 const int maxn = 1e5 + 10;
     13 const int INF = 1 << 30;
     14 int dir[4][2] = {1,0,0,1,-1,0,0,-1};
     15 int T, n, m, x;
     16 bool first;
     17 struct edge
     18 {
     19     int u, v, w;
     20     bool used, equal, del;//used表示是否在MST中,equal表示边是否是相等,del表示求MST中删除的边
     21     bool operator <(const edge& a)const
     22     {
     23         return w < a.w;
     24     }
     25 };
     26 edge a[maxn];
     27 int par[600], high[600];
     28 //初始化n个元素
     29 void init(int n)
     30 {
     31     for(int i = 0; i < n; i++)
     32     {
     33         par[i] = i;
     34         high[i] = 0;
     35     }
     36 }
     37 //查询树的根
     38 int Find(int x)
     39 {
     40     return par[x] == x ? x : par[x] = Find(par[x]);//路径压缩
     41 }
     42 void unite(int x, int y)
     43 {
     44     x = Find(x);
     45     y = Find(y);
     46     if(x == y)return;
     47     if(high[x] < high[y])par[x] = y;//y的高度高,将x的父节点设置成y
     48     else
     49     {
     50         par[y] = x;
     51         if(high[x] == high[y])high[x]++;
     52     }
     53 }
     54 int kruskal(int n, int m)//点数n,边数m
     55 {
     56     int sum_mst = 0;//mst权值
     57     int num= 0;//已经选择的边的边数
     58     sort(a, a + m);//边进行排序
     59     init(n);//初始化并查集
     60     for(int i = 0; i < m; i++)
     61     {
     62         int u = a[i].u;
     63         int v = a[i].v;
     64         if(a[i].del)continue;
     65         if(Find(u - 1) != Find(v - 1))//图最开始的下标是1,并查集是0
     66         {
     67             //printf("%d %d %d
    ", u, v, a[i].w);
     68             sum_mst += a[i].w;
     69             num++;
     70             unite(u - 1, v - 1);
     71             if(first)a[i].used = 1;//标记第一次MST的边
     72         }
     73         if(num >= n - 1)break;
     74     }
     75     //printf("weight of mst is %d
    ", sum_mst);
     76     return sum_mst;
     77 }
     78 int main()
     79 {
     80     cin >> T;
     81     while(T--)
     82     {
     83         cin >> n >> m;
     84         for(int i = 0; i < m; i++)
     85         {
     86             cin >> a[i].u >> a[i].v >> a[i].w;
     87             a[i].used = a[i].equal = a[i].del = 0;
     88         }
     89         sort(a, a + m);
     90         for(int i = 0; i < m; i++)//标记权值相同的边
     91         {
     92             int j = i + 1;
     93             for(; j < m; j++)
     94             {
     95                 if(a[j].w == a[i].w)a[i].equal = a[j].equal = 1;
     96                 else break;
     97             }
     98             i = j - 1;
     99         }
    100         first = 1;
    101         int mst1 = kruskal(n, m);
    102         first = 0;
    103         int flag = 0;
    104         for(int i = 0; i < m; i++)
    105         {
    106             if(a[i].used && a[i].equal)//依次删除第一次MST中相等的边,再次求MST
    107             {
    108                 a[i].del = 1;
    109                 int mst2 = kruskal(n, m);
    110                 if(mst1 == mst2)
    111                 {
    112                     flag = 1;
    113                     cout<<"Not Unique!"<<endl;
    114                     break;
    115                 }
    116                 a[i].del = 0;//删除的标记清除
    117             }
    118         }
    119         if(!flag)cout<<mst1<<endl;
    120     }
    121     return 0;
    122 }
  • 相关阅读:
    开发实例
    一张图解析FastAdmin中的表格列表的功能
    fastAdmin进阶
    detailFormatter bootstrapTable
    responseHandler
    自定义PDO封装类
    bootstrapTable
    Thread Safety
    FastAdmin 基本知识流程一栏
    thinkphp5 Request请求类
  • 原文地址:https://www.cnblogs.com/fzl194/p/8727614.html
Copyright © 2011-2022 走看看