zoukankan      html  css  js  c++  java
  • poj 1679 The Unique MST(次小生成树)

    题意:判断最小生成树是否唯一。

    分析:只需要判断最小生成树与次小生成树的总权值是否相等。

    判断次小生成树的方法:

    kruskal O(n^3):先求一次最小生成树,然后枚举去掉生成树中的边,再求n-1次最小生成树,去最小的一棵。

    prim O(n^2):先求一次最小生成树,记录树上的边,并且保存每个环中的最大边,然后用一次DP枚举掉树上的边,更新生成树的权和,取最小值。

    kruskal
      1 /*
      2 Author:Zhaofa Fang
      3 Lang:C++
      4 */
      5 #include <cstdio>
      6 #include <cstdlib>
      7 #include <sstream>
      8 #include <iostream>
      9 #include <cmath>
     10 #include <cstring>
     11 #include <algorithm>
     12 #include <string>
     13 #include <utility>
     14 #include <vector>
     15 #include <queue>
     16 #include <stack>
     17 #include <map>
     18 #include <set>
     19 using namespace std;
     20 
     21 typedef long long ll;
     22 #define DEBUG(x) cout<< #x << ':' << x << endl
     23 #define REP(i,n) for(int i=0;i < (n);i++)
     24 #define FOR(i,s,t) for(int i = (s);i <= (t);i++)
     25 #define FORD(i,s,t) for(int i = (s);i >= (t);i--)
     26 #define PII pair<int,int>
     27 #define PB push_back
     28 #define MP make_pair
     29 #define ft first
     30 #define sd second
     31 #define lowbit(x) (x&(-x))
     32 #define INF (1<<30)
     33 
     34 
     35 const int maxn = 5050;
     36 int pa[111],a[111];
     37 struct Edge
     38 {
     39     int u,v,w;
     40 }edge[maxn];
     41 
     42 bool cmp(Edge x,Edge y)
     43 {
     44     return x.w < y.w;
     45 }
     46 void init(int n)
     47 {
     48     FOR(i,1,n)pa[i] = i;
     49 }
     50 int findset(int x)
     51 {
     52     return x == pa[x] ? x : pa[x] = findset(pa[x]);
     53 }
     54 int kruskal(int n,int m,int key)
     55 {
     56     init(n);
     57     int ans = 0,cnt=0;
     58     REP(i,m)
     59     {
     60         if(i == key)continue;
     61         int x = findset(edge[i].u),y=findset(edge[i].v);
     62         if(x != y)
     63         {
     64             pa[x] = y;ans += edge[i].w;cnt++;
     65         }
     66         if(cnt == n-1)return ans;
     67     }
     68     return -INF;
     69 }
     70 int main()
     71 {
     72     //freopen("in","r",stdin);
     73     int T;
     74     scanf("%d",&T);
     75     while(T--)
     76     {
     77         int n,m;
     78         scanf("%d%d",&n,&m);
     79         REP(i,m)scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
     80         sort(edge,edge+m,cmp);
     81         int ans = 0,cnt=0;
     82         init(n);
     83         REP(i,m)//最小生成树
     84         {
     85             int x = findset(edge[i].u),y=findset(edge[i].v);
     86             if(x != y)
     87             {
     88                 pa[x] = y;ans += edge[i].w;a[cnt++]=i;
     89             }
     90             if(cnt == n-1)break;
     91         }
     92         REP(i,n-1)
     93         {
     94             int tmp = kruskal(n,m,a[i]);
     95             if(ans == tmp)
     96             {
     97                 ans = -INF;break;
     98             }
     99         }
    100         if(ans == -INF)puts("Not Unique!");
    101         else printf("%d\n",ans);
    102     }
    103     return 0;
    104 }
    prim
     1 /*
     2 Author:Zhaofa Fang
     3 Lang:C++
     4 */
     5 #include <cstdio>
     6 #include <cstdlib>
     7 #include <sstream>
     8 #include <iostream>
     9 #include <cmath>
    10 #include <cstring>
    11 #include <algorithm>
    12 #include <string>
    13 #include <utility>
    14 #include <vector>
    15 #include <queue>
    16 #include <stack>
    17 #include <map>
    18 #include <set>
    19 using namespace std;
    20 
    21 typedef long long ll;
    22 #define DEBUG(x) cout<< #x << ':' << x << endl
    23 #define REP(i,n) for(int i=0;i < (n);i++)
    24 #define FOR(i,s,t) for(int i = (s);i <= (t);i++)
    25 #define FORD(i,s,t) for(int i = (s);i >= (t);i--)
    26 #define PII pair<int,int>
    27 #define PB push_back
    28 #define MP make_pair
    29 #define ft first
    30 #define sd second
    31 #define lowbit(x) (x&(-x))
    32 #define INF (1<<30)
    33 
    34 
    35 const int maxn = 5050;
    36 int maz[maxn][maxn],path[maxn][maxn];
    37 bool vist[maxn];
    38 int dist[maxn],pre[maxn],Stack[maxn];
    39 int n,m;
    40 void init(void){
    41     FOR(i,1,n)FOR(j,1,n)maz[i][j] = INF, path[i][j] = 0;
    42 }
    43 int prim(int s){
    44     FOR(i,1,n)dist[i] = maz[s][i],vist[i] = 0,pre[i] = s;
    45     int top =  0,sum = 0;
    46     vist[s] = 1,dist[s] = 0, Stack[top++] = s;
    47     while(1){
    48         int u = -1;
    49         FOR(i,1,n)
    50             if(!vist[i] && (u == - 1 || dist[u] > dist[i]))
    51                 u = i;
    52         if(u == -1)break;
    53         sum += dist[u],Stack[top++] =  u,vist[u] = 1;
    54         REP(i,top){
    55             if(Stack[i] == u)continue;
    56             path[Stack[i]][u] = max(path[pre[u]][u],dist[u]);
    57             path[u][Stack[i]] = path[Stack[i]][u];
    58         }
    59         FOR(i,1,n)
    60             if(!vist[i] && (maz[u][i]<dist[i]))
    61                 dist[i] = maz[u][i],pre[i] = u;
    62     }
    63     return sum;
    64 }
    65 void SMT(void){
    66     int Min = INF,sum = prim(1);
    67     FOR(i,1,n-1)
    68         FOR(j,i+1,n)
    69             if(pre[i] != j && pre[j] != i && maz[i][j] < INF)
    70                 Min = min(Min, sum  - path[i][j] + maz[i][j]);
    71     if(Min == sum)puts("Not Unique!");
    72     else printf("%d\n",sum);
    73 }
    74 int main(){
    75     //freopen("in","r",stdin);
    76     int T;
    77     scanf("%d",&T);
    78     while(T--){
    79         scanf("%d%d",&n,&m);
    80         init();
    81         int u,v,w;
    82         while(m--)
    83         {
    84             scanf("%d%d%d",&u,&v,&w);
    85             maz[u][v] = maz[v][u] = w;
    86         }
    87         SMT();
    88     }
    89     return 0;
    90 }
  • 相关阅读:
    20145334赵文豪 《信息安全系统设计基础》第2周学习总结
    20145334赵文豪《信息安全系统设计基础》第1周学习总结
    关于第五周大家学习问题的总结
    20145334 第五次 java 实验报告
    20145334 《Java程序设计》第10周学习总结
    实验四 Android开发基础
    # 20145334 《Java程序设计》第9周学习总结
    20145334实验三《敏捷开发与XP实践》
    实验二:面向对象设计
    程序的机器级表示内容补充及扩展
  • 原文地址:https://www.cnblogs.com/fzf123/p/2806346.html
Copyright © 2011-2022 走看看