链接:
http://acm.hdu.edu.cn/showproblem.php?pid=4738
题目大意:
曹操有很多岛屿,然后呢需要建造一些桥梁将所有的岛屿链接起来,周瑜要做的是就是不让曹操将所有岛屿连接起来,每个座桥有人在守卫, 周瑜只能炸一座桥,并且他派人去炸桥只能派的人数必须 大于等于守桥的人数。
输出最小的炸桥人数, 要是没有答案就输出 -1
代码:
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <cstdlib> #include <algorithm> #include <vector> using namespace std; #define INF 0x7ffffff #define N 100005 typedef long long LL; struct node { int e, w; node (int e=0, int w=0):e(e),w(w){} }; int low[N], dfn[N], Time, n, m; int f[N]; int bri[N]; vector < vector <node> > G; void Init() { memset(dfn, 0, sizeof(dfn)); memset(low, 0, sizeof(low)); memset(f, 0, sizeof(f)); memset(bri, -1, sizeof(bri)); Time = 0; G.clear(); G.resize(n+2); } void Tarjan(int u, int fa) { low[u] = dfn[u] = ++Time; f[u] = fa; int len = G[u].size(), k = 0; node v; for(int i=0; i<len; i++) { v = G[u][i]; if(!k && v.e==fa) { k++; continue; } if(!low[v.e]) { Tarjan(v.e, u); low[u] = min(low[u], low[v.e]); } else low[u] = min(low[u], dfn[v.e]); if(dfn[u] < low[v.e]) bri[v.e] = v.w; if(k==2 && bri[v.e]!=-1) bri[v.e] = -1; } } void Slove() { int ans = INF, i; Tarjan(1, 1); for(i=2; i<=n; i++) { if(!low[i]) break; } if(i!=n+1) { puts("0"); return ; } for(i=1; i<=n; i++) { if(bri[i]!=-1) ans = min(ans, bri[i]); } if(ans==0) ans ++; if(ans==INF) ans = -1; printf("%d\n", ans); } int main() { while(scanf("%d%d", &n, &m), m+n) { Init(); for(int i=0; i<m; i++) { int a, b, c; scanf("%d%d%d", &a, &b, &c); G[a].push_back(node(b,c)); G[b].push_back(node(a,c)); } Slove(); } return 0; }
勿忘初心