标签:
题目链接:http://poj.org/problem?id=3177
题意:有n个牧场,Bessie 要从一个牧场到另一个牧场,要求至少要有2条独立的路可以走。现已有m条路,求至少要新建多少条路,使得任何两个牧场之间至少有两条独立的路。两条独立的路是指:没有公共边的路,但
可以经过同一个中间顶点。
#include <iostream> #include <cstdlib> #include <cstdio> #include <algorithm> #include <vector> #include <queue> #include <cmath> #include <stack> #include <cstring> using namespace std; #define INF 0xfffffff #define N 5100 int low[N], dfn[N], f[N], block[N],du[N]; vector<vector<int> > G; int n, Time, m, cnt; stack<int>sta; void Init() { G.clear(); G.resize(n+1); Time = cnt = 0; memset(low, 0, sizeof(low)); memset(dfn, 0, sizeof(dfn)); memset(du, 0, sizeof(du)); memset(f, 0, sizeof(f)); } void Tarjan(int u, int father) { f[u] = father; dfn[u] = low[u] = ++Time; int len = G[u].size(), v, k=0; sta.push(u); for(int i=0; i<len; i++) { v = G[u][i]; if(v == father && !k) { k++; continue; } if(!dfn[v]) { Tarjan(v, u); low[u] = min(low[u], low[v]); } else { low[u] = min(low[u], dfn[v]); } } if(dfn[u] == low[u]) { do { v = sta.top();sta.pop(); block[v] = cnt; }while(u!=v); cnt++; } } int main() { int a, b; while(scanf("%d %d", &n, &m)!=EOF) { Init(); while(m--) { scanf("%d %d", &a, &b); G[a].push_back(b); G[b].push_back(a); } for(int i=1; i<=n; i++) if(!dfn[i]) Tarjan(i,-1); for(int i=1; i<=n; i++) { int v = f[i]; if(v == -1) { continue; } if(block[i] != block[v]) { du[block[i] ]++; du[block[v] ]++; } } int ans = 0; for(int i=0; i<cnt; i++) { if(du[i]==1) ans++; } printf("%d\n",(ans+1)/2); } return 0; }
Redundant Paths---poj3177(双连通分量)
标签:
原文地址:http://www.cnblogs.com/zhengguiping--9876/p/4713353.html