Hdu 4738 Caocao's Bridges (连通图+桥)

题目链接:

  Hdu 4738 Caocao's Bridges

题目描述:

  有n个岛屿,m个桥,问是否可以去掉一个花费最小的桥,使得岛屿边的不连通?

解题思路:

  去掉一个边使得岛屿不连通,那么去掉的这个边一定是一个桥,所以我们只需要求出来所有的桥,然后比较每个桥的花费,选取最小的那个就好。

看起来很简单的样子哦!但是这个题目有很多的细节:

  A:题目中有重边,以后写Tarjan还是清一色判断重边吧。(除非题目特别要求)

  B:m个桥有可能连通不了这n个桥,这个时候不需要花费。

  C:当最小花费桥的花费是0的话,应该输出1。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <iostream>
  4 #include <algorithm>
  5 using namespace std;
  6 
  7 typedef long long LL;
  8 const int maxn = 1005;
  9 const int INF = 0x3f3f3f3f;
 10 struct node
 11 {
 12     int to, next, num;
 13 } edge[maxn*maxn];
 14 int head[maxn], low[maxn], dfn[maxn], stack[maxn];
 15 int id[maxn], cnt, tot, top, ntime;
 16 
 17 void init ()
 18 {
 19     cnt = tot = top = ntime = 0;
 20     memset (id, 0, sizeof(id));
 21     memset (low, 0, sizeof(low));
 22     memset (dfn, 0, sizeof(dfn));
 23     memset (head, -1, sizeof(head));
 24     memset (stack, 0, sizeof(stack));
 25 }
 26 void Add (int from, int to, int num)
 27 {
 28     edge[tot].to = to;
 29     edge[tot].num = num;
 30     edge[tot].next = head[from];
 31     head[from] = tot ++;
 32 }
 33 void Tarjan (int u, int father)
 34 {
 35     int k = 0;
 36     low[u] = dfn[u] = ++ntime;
 37     stack[top++] = u;
 38     for (int i=head[u]; i!=-1; i=edge[i].next)
 39     {
 40         int v = edge[i].to;
 41         if (v == father && !k)
 42         {
 43             k ++;
 44             continue;
 45         }
 46         if (!dfn[v])
 47         {
 48             Tarjan (v, u);
 49             low[u] = min (low[u], low[v]);
 50         }
 51         else
 52             low[u] = min (low[u], dfn[v]);
 53     }
 54     if (low[u] == dfn[u])
 55     {
 56         cnt ++;
 57         while (1)
 58         {
 59             int v = stack[--top];
 60             id[v] = cnt;
 61             if (v == u)
 62                 break;
 63         }
 64     }
 65 }
 66 void solve (int n)
 67 {
 68     int mini = INF, k = 0;
 69     for (int i=1; i<=n; i++)
 70         if (!dfn[i])
 71         {
 72             k ++;
 73             Tarjan(i, 0);
 74         }
 75     if (cnt == 1)
 76     {
 77         printf ("-1
");
 78         return ;
 79     }
 80     if (k > 1)
 81     {
 82         printf ("0
");
 83         return ;
 84     }
 85     for (int i=1; i<=n; i++)
 86         for (int j=head[i]; j!=-1; j=edge[j].next)
 87         {
 88             int u = id[i];
 89             int v = id[edge[j].to];
 90             if (u != v && mini > edge[j].num)
 91                 mini = edge[j].num;
 92         }
 93     if (mini == 0)
 94         mini ++;
 95     printf("%d
", mini);
 96 }
 97 int main ()
 98 {
 99     int n, m;
100     while (scanf ("%d %d", &n, &m), n+m)
101     {
102         int u, v, num;
103         init ();
104         while (m --)
105         {
106             scanf ("%d %d %d", &u, &v, &num);
107             Add (u, v, num);
108             Add (v, u, num);
109         }
110         solve (n);
111     }
112     return 0;
113 }
本文为博主原创文章,未经博主允许不得转载。
原文地址:https://www.cnblogs.com/alihenaixiao/p/4668624.html