标签:
3 3 1 2 7 2 3 4 3 1 4 3 2 1 2 7 2 3 4 0 0
-1 4
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> #define maxn 1010 #define maxm 1000100 #define INF 0x3f3f3f3f using namespace std; int n, m; int low[maxn]; int dfn[maxn]; int head[maxn], cnt; int dfs_clock; int mark;//判断图是否连通 struct node{ int u, v, w, cnt, next; }; node edge[maxm]; void init(){ cnt = 0; memset(head, -1, sizeof(head)); } void add(int u, int v, int w){ edge[cnt] = {u, v, w, 0, head[u]}; head[u] = cnt++; edge[cnt] = {v, u, w, 0, head[v]}; head[v] = cnt++; } void input(){ while(m--){ int u, v, w; scanf("%d%d%d", &u, &v, &w); add(u, v, w); } } void tarjin(int u, int fa){ low[u] = dfn[u] = ++dfs_clock; int flag = 1; for(int i = head[u]; i != -1; i = edge[i].next){ int v = edge[i].v; if(flag && v == fa){//去重边,重边不可能是桥 flag = 0; continue; } if(!dfn[v]){ tarjin(v, u); low[u] = min(low[u], low[v]); if(dfn[u] < low[v])//是桥 edge[i].cnt = edge[i ^ 1].cnt = 1; } else low[u] = min(low[u], dfn[v]); } } void find(){ memset(dfn, 0, sizeof(dfn)); memset(low, 0, sizeof(low)); dfs_clock = 0; tarjin(1, 1); mark = 1; for(int i = 1; i <= n; ++i){ if(!dfn[i]){ mark = 0; return ; } } } void solve(){ if(!mark) printf("0\n"); else{ int ans = INF; for(int i = 0; i < cnt; ++i){ if(edge[i].cnt) ans = min(ans, edge[i].w); } if(ans == INF) ans = -1; if(ans == 0) ans = 1; printf("%d\n", ans); } } int main (){ while(scanf("%d%d", &n, &m), n || m){ init(); input(); find(); solve(); } return 0; }
另一种去重边的方式,对这一题来说处理时间比较慢
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> #define maxn 1010 #define maxm 1000100 #define INF 0x3f3f3f3f using namespace std; int n, m; int low[maxn]; int dfn[maxn]; int head[maxn], cnt; int dfs_clock; int mark;//判断图是否连通 struct node{ int u, v, w, cnt, next, again;//again标记是不是有重边 }; node edge[maxm]; void init(){ cnt = 0; memset(head, -1, sizeof(head)); } void add(int u, int v, int w){ int i; //标记重边 for(i = head[u]; i != -1; i = edge[i].next){ if(edge[i].v == v){ break; } } if(i != -1) edge[i].again = 1; else{ edge[cnt] = {u, v, w, 0, head[u], 0}; head[u] = cnt++; } } void input(){ while(m--){ int u, v, w; scanf("%d%d%d", &u, &v, &w); add(u, v, w); add(v, u, w); } } void tarjin(int u, int fa){ low[u] = dfn[u] = ++dfs_clock; for(int i = head[u]; i != -1; i = edge[i].next){ int v = edge[i].v; if(v == fa) continue; if(!dfn[v]){ tarjin(v, u); low[u] = min(low[u], low[v]); if(dfn[u] < low[v] && edge[i].again == 0)//是桥 edge[i].cnt = edge[i ^ 1].cnt = 1; } else low[u] = min(low[u], dfn[v]); } } void find(){ memset(dfn, 0, sizeof(dfn)); memset(low, 0, sizeof(low)); dfs_clock = 0; tarjin(1, -1); mark = 1; for(int i = 1; i <= n; ++i){ if(!dfn[i]){ mark = 0; return ; } } } void solve(){ if(!mark) printf("0\n"); else{ int ans = INF; for(int i = 0; i < cnt; ++i){ if(edge[i].cnt) ans = min(ans, edge[i].w); } if(ans == INF) ans = -1; if(ans == 0) ans = 1; printf("%d\n", ans); } } int main (){ while(scanf("%d%d", &n, &m), n || m){ init(); input(); find(); solve(); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
HDU 4738 --Caocao's Bridges 【无向图边双联通 && 求权值最小的桥 && 模板】
标签:
原文地址:http://blog.csdn.net/hpuhjh/article/details/47683907