标签:
Description:
Input:
Output:
Sample Input:
7 7 1 2 2 3 3 4 2 5 4 5 5 6 5 7
Sample Output:
2
Hint:
1 2 3Building new paths from 1 to 6 and from 4 to 7 satisfies the conditions.
+---+---+
| |
| |
6 +---+---+ 4
/ 5
/
/
7 +
1 2 3Check some of the routes:
+---+---+
: | |
: | |
6 +---+---+ 4
/ 5 :
/ :
/ :
7 + - - - -
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int N=50010; struct node { int v, next; } no[N]; int r[N], be[N], Stack[N], vis[N], head[N], dfn[N], low[N]; bool use[5010][5010]; int ans, Time, top, k; void Init() { memset(head, -1, sizeof(head)); memset(dfn, 0, sizeof(dfn)); memset(low, 0, sizeof(low)); memset(vis, 0, sizeof(vis)); memset(r, 0, sizeof(r)); ///r数组存放与第i个点相邻的点与其强连通分量不同的个数 Time = top = ans = k = 0; } void Add(int a, int b) { no[k].v = b; no[k].next = head[a]; head[a] = k++; } void Tarjan(int u, int fa) { int v, i; Stack[top++] = u; vis[u] = 1; dfn[u] = low[u] = ++Time; for (i = head[u]; i != -1; i = no[i].next) { v = no[i].v; if (!dfn[v]) { Tarjan(v, u); low[u] = min(low[u], low[v]); } else if (v != fa) low[u] = min(low[u], dfn[v]); } if (dfn[u] == low[u]) { ++ans; do { v = Stack[--top]; vis[v] = 0; be[v] = ans; }while(u != v); } } int main () { int n, m, a, b, i, j, num; while (scanf("%d%d", &n, &m) != EOF) { Init(); num = 0; while (m--) { scanf("%d%d", &a, &b); if (!use[a][b]) ///去重边 { Add(a, b); Add(b, a); use[a][b] = use[b][a] = 1; } } Tarjan(1, 1); ///因为任意的两个点都至少有一条边,所以查找一次就行 for (i = 1; i <= n; i++) { for (j = head[i]; j != -1; j = no[j].next) { if (be[i] != be[no[j].v]) ///be数组存放的是该点属于第几个强连通分量 r[be[i]]++; } } for (i = 1; i <= ans; i++) if (r[i] == 1) num++; ///只有当等于1时,该点才是叶子节点 printf("%d\n", (num+1)/2); ///让每个叶子节点至少连接两条边,只有这样才能让任意两点之间至少有两条路 } return 0; }
POJ 3177 Redundant Paths(无向图缩点)
标签:
原文地址:http://www.cnblogs.com/syhandll/p/4741467.html