找人去炸边,炸完之后分成两个连通块(炸割桥)
每条边上有w个守卫,派去炸桥的人不能比守卫少
所以,
如果原本不连通,那么输出0
如果没有桥,输出-1
如果有桥没有守卫,那么是输出1,而不是0(trick)
1 #pragma warning(disable:4996) 2 #pragma comment(linker, "/STACK:1024000000,1024000000") 3 #include <iostream> 4 #include <stdio.h> 5 #include <string.h> 6 #include <vector> 7 #include <stack> 8 #include <queue> 9 #include <math.h> 10 #include <algorithm> 11 #include <map> 12 #include <set> 13 #include <functional> 14 using namespace std; 15 const int INF = 1 << 30; 16 typedef __int64 LL; 17 /* 18 要摧毁的边只能是桥 19 20 */ 21 22 const int N = 1000 + 10; 23 int head[N], next[N*N], to[N*N], dist[N*N], e; 24 int dfn[N], low[N], dfs_clock, ans; 25 void init() 26 { 27 memset(head, -1, sizeof(head)); 28 memset(dfn, 0, sizeof(dfn)); 29 memset(low, 0, sizeof(low)); 30 dfs_clock = e = 0; 31 ans = INF; 32 } 33 void addEdge(int u, int v, int dis) 34 { 35 to[e] = v; 36 dist[e] = dis; 37 ::next[e] = head[u]; 38 head[u] = e++; 39 } 40 void tarjan(int u, int fa) 41 { 42 dfn[u] = low[u] = ++dfs_clock; 43 bool flag = false; 44 for (int i = head[u]; i + 1; i = ::next[i]) 45 { 46 if (to[i] == fa && !flag) 47 { 48 flag = true; 49 continue; 50 } 51 if(dfn[to[i]]==0) 52 tarjan(to[i], u); 53 low[u] = min(low[to[i]], low[u]); 54 if (low[to[i]] > dfn[u]) 55 ans = min(ans, dist[i]); 56 } 57 } 58 int main() 59 { 60 int n, m; 61 while (scanf("%d%d", &n, &m),n+m) 62 { 63 int u, v, dis; 64 init(); 65 for (int i = 1;i <= m;++i) 66 { 67 scanf("%d%d%d", &u, &v, &dis); 68 addEdge(u, v, dis); 69 addEdge(v, u, dis); 70 } 71 ans = INF; 72 tarjan(1, -1); 73 bool flag = true; 74 for (int i = 1;i <= n;++i) 75 if (dfn[i] == 0) 76 { 77 printf("0\n"); 78 flag = false; 79 break; 80 } 81 if (!flag)continue; 82 if (ans == INF) 83 ans = -1; 84 if (ans == 0)ans = 1; 85 printf("%d\n", ans); 86 } 87 return 0; 88 }
时间: 2024-10-08 02:47:26