题目链接:
题目描述:
有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\n"); 78 return ; 79 } 80 if (k > 1) 81 { 82 printf ("0\n"); 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\n", 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 }
Hdu 4738 Caocao's Bridges (连通图+桥)
时间: 2024-10-10 18:03:33