码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 3694 边双连通分量+LCA

时间:2014-10-12 01:22:37      阅读:288      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   color   io   os   ar   for   strong   

Network
Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 6837   Accepted: 2435

Description

A network administrator manages a large network. The network consists of N computers and M links between pairs of computers. Any pair of computers are connected directly or indirectly by successive links, so data can be transformed between any two computers. The administrator finds that some links are vital to the network, because failure of any one of them can cause that data can‘t be transformed between some computers. He call such a link a bridge. He is planning to add some new links one by one to eliminate all bridges.

You are to help the administrator by reporting the number of bridges in the network after each new link is added.

Input

The input consists of multiple test cases. Each test case starts with a line containing two integers N(1 ≤ N ≤ 100,000) and M(N - 1 ≤ M ≤ 200,000).
Each of the following M lines contains two integers A and B ( 1≤ A ≠ B ≤ N), which indicates a link between computer A and B. Computers are numbered from 1 to N. It is guaranteed that any two computers are connected in the initial network.
The next line contains a single integer Q ( 1 ≤ Q ≤ 1,000), which is the number of new links the administrator plans to add to the network one by one.
The i-th line of the following Q lines contains two integer A and B (1 ≤ A ≠ B ≤ N), which is the i-th added new link connecting computer A and B.

The last test case is followed by a line containing two zeros.

Output

For each test case, print a line containing the test case number( beginning with 1) and Q lines, the i-th of which contains a integer indicating the number of bridges in the network after the first i new links are added. Print a blank line after the output for each test case.

Sample Input

3 2
1 2
2 3
2
1 2
1 3
4 4
1 2
2 1
2 3
1 4
2
1 2
3 4
0 0

Sample Output

Case 1:
1
0

Case 2:
2
0


题目意思:
给一个n个结点m条边的无向图,下面Q个操作,每个操作为x,y即在点x和y之间连一条边,每操作一次就输出该图的桥的个数。


思路:
画了一下图发现,当x和y之间连边的时候,x->lca(x,y)->y路径上的所有的桥都不是桥了(桥不会增加只会减少或不变),所以思路就有了:先trajan求出所有的桥标记一下,然后每次对x,y添边的时候就找他们的最近公共祖先,把路径上的桥的标记改成不是桥的标记,桥的数目--。由于时限5000MS,所以这样虽然暴力但是还是能过得。


代码:
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <vector>
 6 #include <queue>
 7 using namespace std;
 8 
 9 #define N 100005
10 
11 vector<int>ve[N];
12 int low[N], dfn[N], dfn_clock;
13 int father[N], dep[N], bridge[N], b_num;
14 int n, m;
15 
16 void init(){
17     for(int i=0;i<=n;i++){
18         ve[i].clear();
19     }
20     memset(low,0,sizeof(low));
21     memset(dfn,0,sizeof(dfn));
22     memset(dep,0,sizeof(dep));
23     memset(bridge,0,sizeof(bridge));
24 }
25 
26 void tarjan(int u,int fa,int d){
27     dep[u]=d;
28     father[u]=fa;
29     int i, j, k, v;
30     low[u]=dfn[u]=++dfn_clock;
31     for(i=0;i<ve[u].size();i++){
32         v=ve[u][i];
33         if(v==fa) continue;
34         if(!dfn[v]){
35             tarjan(v,u,d+1);
36             low[u]=min(low[u],low[v]);
37             if(low[v]>dfn[u]){
38                 bridge[v]=1;
39                 ++b_num;
40             }
41         }
42         else low[u]=min(low[u],dfn[v]);
43     }
44 }
45 
46 void lca(int x,int y){
47     if(dep[x]<dep[y]) swap(x,y);
48     while(dep[x]>dep[y]){
49         if(bridge[x]){
50              --b_num;bridge[x]=0;
51         }
52         x=father[x];
53     }
54     while(x!=y){
55         if(bridge[x]){
56             --b_num;bridge[x]=0;
57         } 
58         if(bridge[y]){
59             --b_num;bridge[y]=0;
60         } 
61         x=father[x];y=father[y];
62     }
63 }
64 
65 main()
66 {
67     int i, j, k, x, y, q, kase=1;;
68     while(scanf("%d %d",&n,&m)==2&&(n+m)){
69         init();
70         while(m--){
71             scanf("%d %d",&x,&y);
72             ve[x].push_back(y);ve[y].push_back(x);
73         }
74         b_num=dfn_clock=0;
75             tarjan(1,1,1);
76         scanf("%d",&q);
77         printf("Case %d:\n",kase++);
78     //    printf("b_num==%d\n",b_num);
79         while(q--){
80             scanf("%d %d",&x,&y);
81             lca(x,y);
82             printf("%d\n",b_num);
83         }
84     }
85 }

 

POJ 3694 边双连通分量+LCA

标签:des   style   blog   color   io   os   ar   for   strong   

原文地址:http://www.cnblogs.com/qq1012662902/p/4019942.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!