题目大意:
曹操有很多岛屿,然后呢需要建造一些桥梁将所有的岛屿链接起来,周瑜要做的是就是不让曹操将所有岛屿连接起来,每个座桥有人在守卫, 周瑜只能炸一座桥,并且他派人去炸桥只能派的人数必须 大于等于守桥的人数。
输出最小的炸桥人数, 要是没有答案就输出 -1
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <cstdlib> #include <algorithm> #include <vector> usingnamespace std; #define INF 0x7ffffff #define maxn 100005 typedef longlong LL; #define Min(a,b) (a<b?a:b) struct node { int e, w; node(int e=0,int w=0): e(e), w(w) {} }; int low[maxn], dfn[maxn], Time, m, n; int Father[maxn]; int bridge[maxn]; vector<vector<node> > G; void init() { memset(dfn, 0, sizeof(dfn)); memset(low, 0, sizeof(low)); memset(Father, 0,sizeof(Father)); memset(bridge, -1, sizeof(bridge)); Time = 0; G.clear(); G.resize(n+2); } void Tarjan(int u,int fa) { low[u] = dfn[u] = ++Time; Father[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]) bridge[v.e] = v.w; if(k == 2 && bridge[v.e] != -1) bridge[v.e] = -1; } } void solve() { 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(bridge[i] != -1) { ans = min(bridge[i], ans); } } if(ans == 0) ans ++; if(ans == INF) ans = -1; printf("%d ", 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)); } solve(); } return0; }