zoukankan      html  css  js  c++  java
  • poj 1679 The Unique MST 判断最小生成树是否唯一(图论)

    借用的是Kruskal的并查集,算法中的一点添加和改动。

    通过判定其中有多少条可选的边,然后跟最小生成树所需边做比较,可选的边多于所选边,那么肯定方案不唯一。

    如果不知道这个最小生成树的算法,还是先去理解下这个算法的原理,再继续看。

    多加的几行与cnt2很类似的cnt1统计,是统计当前未选边中相同长度的边还有哪些可以选,但不标记,只是为了把当前可选的边全部统计出来。

    其他细节,自己要细心点~

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <stdlib.h>
     4 #include <math.h>
     5 #include <iostream>
     6 #include <algorithm>
     7 #include <climits>
     8 #include <queue>
     9 
    10 using namespace std;
    11 
    12 //Kruskal算法 求最小生成树是否唯一
    13 
    14 const int MAX = 110;
    15 int F[MAX];
    16 struct Edge
    17 {
    18     int u,v,w;
    19 } edge[MAX*MAX];
    20 int tol;
    21 void addedge(int u,int v,int w)
    22 {
    23     edge[tol].u = u;
    24     edge[tol].v = v;
    25     edge[tol++].w = w;
    26 }
    27 bool cmp(Edge a,Edge b)
    28 {
    29     return a.w < b.w;
    30 }
    31 int find(int x)
    32 {
    33     if(F[x] == -1) return x;
    34     else return F[x] = find(F[x]);
    35 }
    36 void Kruskal(int n)
    37 {
    38     memset(F,-1,sizeof(F));
    39     sort(edge,edge+tol,cmp);
    40     int cnt1 = 0,cnt2 =  0;
    41     int ans = 0;
    42     for(int i = 0; i < tol; )
    43     {
    44         int j = i;
    45         while(j < tol && edge[j].w == edge[i].w)
    46         {
    47             int u = edge[j].u;
    48             int v = edge[j].v;
    49             int t1 = find(u);
    50             int t2 = find(v);
    51             if(t1 != t2)
    52             {
    53                 cnt1++;
    54             }
    55             j++;
    56         }
    57         j = i;
    58         while(j < tol && edge[j].w == edge[i].w)
    59         {
    60             int u = edge[j].u;
    61             int v = edge[j].v;
    62             int w = edge[j].w;
    63             int t1 = find(u);
    64             int t2 = find(v);
    65             if(t1 != t2)
    66             {
    67                 ans += w;
    68                 F[t1] = t2;
    69                 cnt2++;
    70             }
    71             j++;
    72         }
    73         i = j;
    74         if(cnt2 == n - 1)
    75             break;
    76     }
    77     //printf("%d %d
    ",cnt1,cnt2);
    78     if(cnt1 > cnt2 || cnt2 != n -1)
    79         printf("Not Unique!
    ");
    80     else
    81         printf("%d
    ",ans);
    82 }
    83 int main(void)
    84 {
    85     int t,m,n,i,x,y,w;
    86     scanf("%d",&t);
    87     while(t--)
    88     {
    89         scanf("%d %d",&n,&m);
    90         tol = 0;
    91         for(i = 0; i < m; i++)
    92         {
    93             scanf("%d %d %d",&x,&y,&w);
    94             addedge(x,y,w);
    95         }
    96         Kruskal(n);
    97     }
    98     return 0;
    99 }
  • 相关阅读:
    jdbc(插入大对象及读取大对象、存储过程)
    jdbc批量插入操作(addBatch)
    javase(Properties集合及学生对象信息录入文本中案例)
    javase模拟斗地主洗牌和发牌(54)
    javase套接字编程
    javase网络编程
    javase多线程复制
    javase文件切割及融合
    设计原则
    模板方法模式
  • 原文地址:https://www.cnblogs.com/henserlinda/p/4695824.html
Copyright © 2011-2022 走看看