zoukankan      html  css  js  c++  java
  • POJ1679判断最小生成树是否唯一

    判断最小生成树是否唯一的思路:
      (1) 对图中每条边,扫描其它边,如果存在权值相同的边,则对该边作标记
      (2) 然后用Kruskal算法求MST
      (3) 求得MST后,如果该MST中为包含作了标记的边,即可判定MST唯一;
           如果包含作了标记的边,则依次去掉这些边再求MST,如果求得的MST
           权值与原MST的权值相同,即可判定MST不唯一

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cstdlib>
      5 #include <algorithm>
      6 using namespace std;
      7 #define N 105
      8 #define M 10050
      9 struct Edge
     10 {
     11     int u,v,w;
     12     int equal;
     13     int del;
     14     int used;
     15 }edge[M];
     16 int father[N],rank[N];
     17 int n,m;
     18 bool first;
     19 
     20 bool cmp(Edge a,Edge b)
     21 {
     22     return a.w < b.w ;
     23 }
     24 
     25 void Init()
     26 {
     27     for(int i=1; i<=n; i++)
     28     {
     29         rank[i] = 1;
     30         father[i] = i;
     31     }
     32 }
     33 
     34 int find(int x)
     35 {
     36     if(father[x] != x)
     37     father[x] = find(father[x]);
     38     return father[x];
     39 }
     40 
     41 void merge(int x,int y)
     42 {
     43     int xf = find(x);
     44     int yf = find(y);
     45     if(rank[xf] > rank[yf])
     46     {
     47         rank[xf] += rank[yf];
     48         father[yf] = xf;
     49     }
     50     else
     51     {
     52         rank[yf] += rank[xf];
     53         father[xf] = yf;
     54     }
     55 }
     56 
     57 int Kruskal()
     58 {
     59     int num = 0;
     60     int sum = 0;
     61     Init();
     62     for(int i=0; i<m; i++)
     63     {
     64         int u = edge[i].u ;
     65         int v = edge[i].v ;
     66         if(edge[i].del) continue;
     67         if(find(u) != find(v))
     68         {
     69             num++;
     70             sum += edge[i].w;
     71             merge(u,v);
     72             if(first) edge[i].used = 1;
     73         }
     74         if(num==n-1) break;
     75     }
     76     if(num<n-1) return -1;
     77     return sum;
     78 }
     79 
     80 int main()
     81 {
     82     int T;
     83     int u,v,w;
     84     scanf("%d",&T);
     85     while(T--)
     86     {
     87         scanf("%d%d",&n,&m);
     88         for(int i=0; i<m; i++)
     89         {
     90             scanf("%d%d%d",&u,&v,&w);
     91             edge[i].u = u ; edge[i].v = v ; edge[i].w = w ;
     92             edge[i].equal = 0 ; edge[i].del = 0 ; edge[i].used = 0 ;
     93         }
     94         for(int i=0; i<m; i++)
     95         for(int j=i+1; j<m; j++)
     96         {
     97             if(edge[i].w == edge[j].w)
     98             edge[i].equal = edge[j].equal = 1;
     99         }
    100         sort(edge,edge+m,cmp);
    101         first = 1;
    102         int sum1 = Kruskal();
    103         int flag = 1;
    104         first = 0;
    105         for(int i=0; i<m; i++)
    106         {
    107             if(edge[i].used && edge[i].equal)
    108             {
    109                 edge[i].del = 1;
    110                 int sum2 = Kruskal();
    111                 if(sum1 == sum2)
    112                 {
    113                     printf("Not Unique!
    ");
    114                     flag = 0;
    115                     break;
    116                 }
    117                 edge[i].del = 0;
    118             }
    119         }
    120         if(flag) printf("%d
    ",sum1);
    121     }
    122     return 0;
    123 }
    View Code
  • 相关阅读:
    Java函数调用
    Java编程工具的介绍
    Java关键字及作用
    Java面向对象
    Java代码内容概述
    Java构造方法
    Java面向对象
    Java数组概述和定义
    JDBC工具类,基于C3P0的数据库连接池,提供获取连接池、获取连接对象、释放资源和封装事务操作的方法
    图片爬虫工具,可以爬取指定网页的图片
  • 原文地址:https://www.cnblogs.com/ar940507/p/3227415.html
Copyright © 2011-2022 走看看