[kuangbin带你飞]专题九 连通图 I - Caocao's Bridges(无向图求桥(割边))(并查集)(坑题)

来源:互联网 发布:mac如何现实隐藏文件 编辑:程序博客网 时间:2024/05/21 10:02

这道题巨坑无比!!!!!

主要由三个坑点:1.如果桥(x,y)上的守卫为0人,输出为1 ,因为需要一个人去扛炸药! 2.包含重边 3.所给的图可能不是连通图!微笑

所以输出为0时ans++,再对重边跳过,因为只有一个炸弹不可能炸两个桥,最后用并查集判断是不是连通图,不是就输出0跳过;

#include<bits/stdc++.h>using namespace std;#define pb(a) push_back(a)const int maxn = 1005;int n,low[maxn],dfn[maxn],f[maxn],times,we[maxn][maxn],m,fa[maxn],ddd[maxn][maxn];  vector<vector<int> > g;void init() {g.clear();g.resize(n+1);memset(low,0,sizeof(low));  memset(dfn,0,sizeof(dfn)); memset(f,0,sizeof(f)); memset(we,0,sizeof(we));memset(ddd,0,sizeof(ddd));times = 0;for(int i = 0;i <= n;i++) fa[i] = i;}void tarjan(int u,int fa) {int len,v;low[u] = dfn[u] = ++times;f[u] = fa;len = g[u].size();for(int i = 0;i < len;i++) {v = g[u][i];if(!dfn[v]) {tarjan(v,u);low[u] = min(low[u],low[v]);}else if(fa != v) low[u] = min(low[u],dfn[v]);}}int query(int x) {return fa[x] == x ? fa[x] : fa[x] = query(fa[x]);}int main() {while(scanf("%d%d",&n,&m) != EOF && (n || m)) {init();for(int i = 1;i <= m;i++) {int u,v,w;scanf("%d%d%d",&u,&v,&w);int a = query(u);int b = query(v);if(a != b) fa[a] = b; g[u].pb(v);g[v].pb(u);if(!we[u][v])we[u][v] = we[v][u] = w;else {ddd[u][v] = ddd[v][u] = 1;}}int dd = query(1),flag = 0;for(int i = 2;i <= n;i++) if(query(i) != dd) {printf("0\n",dd);flag = 1;break;}if(flag) continue;tarjan(1,0);int ans = 100005;for(int i = 1;i <= n;i++) {int v = f[i];if(ddd[v][i]) continue;if(v != 0 && dfn[v] < low[i]) {ans = min(ans,we[i][v]);}}if(ans == 0) ans++;if(ans == 100005) printf("-1\n");else printf("%d\n",ans);}}


0 0
原创粉丝点击