标签:注意 fat minimum sid point pos har off problem
7 7 1 2 2 3 3 4 2 5 4 5 5 6 5 7Sample Output
2Hint
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 + - - - -
题目所求即为把无向图中缩点为一棵树后,再加边使之成为一个边双连通块。所加边数即为(叶子节点数+1)/2,加边方法为每次取两个LCA最远的叶节点,在他们两个中间连一条边,重复取直到加完。
注意:这道题两点之间会有多条边,不能简单的判断 To != father ,必须判断是否为同一条边。因为边为无向边,所以不知道 i+1 和 i-1 那一条和 i 是同一条边。这里介绍一种妙不可言的方法,把每条无向边的编号赋值为这条边的权,所以只需判断两条边权是否相同即可。
1 #include <map> 2 #include <set> 3 #include <cmath> 4 #include <ctime> 5 #include <queue> 6 #include <stack> 7 #include <cstdio> 8 #include <string> 9 #include <vector> 10 #include <cstdlib> 11 #include <cstring> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 #define ll long long 16 #define file(a) freopen(a".in","r",stdin); freopen(a".out","w",stdout); 17 18 inline int gi() 19 { 20 bool b=0; int r=0; char c=getchar(); 21 while(c<‘0‘ || c>‘9‘) { if(c==‘-‘) b=!b; c=getchar(); } 22 while(c>=‘0‘ && c<=‘9‘) { r=r*10+c-‘0‘; c=getchar(); } 23 if(b) return -r; return r; 24 } 25 26 const int inf = 1e9+7, N = 5007, M = 10007; 27 int n,m,num,Deep,f[N],dfn[N],low[N],cd[N]; 28 bool b[N]; 29 stack <int> s; 30 struct data 31 { 32 int nx,to,ds; 33 }da[M]; 34 35 inline void add (int fr,int to,int ds) 36 { 37 da[++num].to=to, da[num].nx=f[fr], da[num].ds=ds, f[fr]=num; 38 } 39 40 inline void tarjan (int o,int fa) 41 { 42 int i,to; 43 dfn[o]=low[o]=++Deep; b[o]=1; 44 for (i=f[o]; i; i=da[i].nx) 45 { 46 to=da[i].to; 47 if (da[i].ds == da[fa].ds) continue; 48 if (!dfn[to]) tarjan (to,i), low[o]=min(low[o],low[to]); 49 else if (b[to]) low[o]=min(low[o],dfn[to]); 50 } 51 b[o]=0; 52 } 53 54 int main() 55 { 56 // file("POJ-3177"); 57 n=gi(), m=gi(); 58 int i,j,x,y; 59 for (i=1; i<=m; i++) 60 { 61 x=gi(), y=gi(); 62 add (x,y,i), add (y,x,i); 63 } 64 for (i=1; i<=n; i++) if (!dfn[i]) tarjan (i,0); 65 for (i=1; i<=n; i++) 66 for (j=f[i]; j; j=da[j].nx) 67 { 68 x=low[da[j].to], y=low[i]; 69 if (x != y) cd[y]++; 70 } 71 x=0; 72 for (i=1; i<=n; i++) if (cd[i] == 1) x++; 73 printf ("%d\n",(x+1)/2); 74 return 0; 75 }
欢迎在评论区提问质疑!
标签:注意 fat minimum sid point pos har off problem
原文地址:http://www.cnblogs.com/y142857/p/6883240.html