标签:判断 space pos 题意 possible ever media size 决定
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 + - - - -
题解:把F个农场看作点、路看作边构造一个无向图G时,图G不存在桥。
也就是问给定一个连通的无向图G,至少要添加几条边,才能使其变为双连通图。
把每一个双连通分量(内部满足条件)缩为一个点,形成一棵树,加(n+1)/2条边就是双连通了(度为1的点个数为n)
注意:判断两个点是不是同一个双连通分量
1.无重边:low值相等就是同一个双连通分量
2.有重边:bfs结束时出栈的就是同一连通分量,好像有点麻烦
这里加了一个判断,不加重边
#include<stdio.h> #include <algorithm> #include <string.h> #define N 5005 #define mes(x) memset(x, 0, sizeof(x)); #define ll __int64 const long long mod = 1e9+7; const int MAX = 0x7ffffff; using namespace std; struct ed{ int to, next; }edge[N*5]; int head[N], top=0; bool mp[N][N]; int pre[N], low[N], dfs_time, out[N]; void addedge(int u,int v){ edge[top].to = v; edge[top].next = head[u]; head[u] = top++; } void dfs(int u,int father){ low[u] = pre[u] = dfs_time++; for(int i=head[u];i!=-1;i=edge[i].next){ int v = edge[i].to; if(v == father) continue; if(!pre[v]){ dfs(v, u); low[u] = min(low[v], low[u]); } else low[u] = min(low[u], pre[v]); } } int main(){ int n, m, t, i, j, a, b; while(~scanf("%d%d", &n, &m)){ memset(head, -1, sizeof(head)); memset(pre,0,sizeof(pre)); memset(low, 0, sizeof(low)); memset(out, 0, sizeof(out)); memset(mp, false, sizeof(mp)); dfs_time = 1;top = 0; for(i=1;i<=m;i++){ scanf("%d%d", &a, &b); if(!mp[a][b]){ mp[a][b] = mp[b][a] = 1; addedge(a, b); addedge(b, a); } } dfs(1,-1); t = 0; for(i=1;i<=n;i++) for(j=head[i];j!=-1;j=edge[j].next){ int v = edge[j].to; if(low[v] != low[i]) out[low[i]]++; } for(i=1;i<=n;i++) if(out[i] == 1) t++; printf("%d\n", (t+1)/2); } }
标签:判断 space pos 题意 possible ever media size 决定
原文地址:http://www.cnblogs.com/Noevon/p/6290905.html