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


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

    有t组数据,给你n个点,m条边,求是否存在相同权值的最小生成树(次小生成树的权值大小等于最小生成树)。

    先求出最小生成树的大小,把最小生成树的边存起来。然后分别枚举最小生成树上的每条边,除了这条边,其他边是否能生成最小生成树,若生成树的权值等于原来最小生成树的权值,则不唯一,否则输出最小生成树的权值。这里我用kruskal比较方便。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <vector>
     6 using namespace std;
     7 const int MAXN = 105;
     8 const int INF = 1e9;
     9 struct edge {
    10     int u , v , cost;
    11 }a[MAXN * MAXN];
    12 typedef pair <int , int> P;
    13 int par[MAXN] , f;
    14 bool vis[MAXN][MAXN];
    15 vector <P> G;
    16 
    17 void init(int n) {
    18     for(int i = 1 ; i <= n ; i++) {
    19         par[i] = i;
    20     }
    21     memset(vis , false , sizeof(vis));
    22     f = 0;
    23     G.clear();
    24 }
    25 
    26 bool cmp(edge a , edge b) {
    27     return a.cost < b.cost;
    28 }
    29 
    30 int Find(int n) {
    31     if(par[n] == n)
    32         return n;
    33     return (par[n] = Find(par[n]));
    34 }
    35 
    36 int kruskal(int m , int n) {
    37     int res = 0 , cont = n;
    38     for(int i = 1 ; i <= m ; i++) {
    39         if(cont == 1)
    40             break;
    41         else if(vis[a[i].u][a[i].v])
    42             continue;
    43         int u = Find(a[i].u) , v = Find(a[i].v);
    44         if(u != v) {
    45             if(!f) {
    46                 G.push_back(P(a[i].u , a[i].v)); // f等于0的时候是求最小生成树的时候,存边操作
    47             }
    48             par[u] = v;
    49             res += a[i].cost;
    50             cont--;
    51         }
    52     }
    53     if(cont == 1)
    54         return res;
    55     return INF;
    56 }
    57 
    58 int main()
    59 {
    60     int t , n , m , u , v , w;
    61     scanf("%d" , &t);
    62     while(t--) {
    63         scanf("%d %d" , &n , &m);
    64         init(n);
    65         for(int i = 1 ; i <= m ; i++) {
    66             scanf("%d %d %d" , &u , &v , &w);
    67             a[i].u = u , a[i].v = v , a[i].cost = w;
    68         }
    69         sort(a + 1 , a + m + 1 , cmp);
    70         int res = kruskal(m , n) , check = 0;
    71         f++;
    72         for(int i = 0 ; i < G.size() ; i++) {
    73             for(int j = 1 ; j <= n ; j++) {
    74                 par[j] = j;
    75             }
    76             vis[G[i].first][G[i].second] = true;
    77             if(res == kruskal(m , n)) {
    78                 check = 1;
    79                 break;
    80             }
    81             vis[G[i].first][G[i].second] = false;
    82         }
    83         if(check) {
    84             printf("Not Unique!
    ");
    85         }
    86         else {
    87             printf("%d
    " , res);
    88         }
    89     }
    90 }
  • 相关阅读:
    事务的特性(ACID)
    网络代理
    防止SpringMVC拦截器拦截js等静态资源文件
    Tomcat配置虚拟目录
    SpringMVC总结(SSM)
    Spring声明式事务总结
    Linux中MySQL忽略表中字段大小写
    MySQL之sql文件的导入导出
    MyBatis总结
    Linux网络
  • 原文地址:https://www.cnblogs.com/Recoder/p/5309082.html
Copyright © 2020-2023  润新知