标签:des style blog color io os ar for strong
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 }
标签:des style blog color io os ar for strong
原文地址:http://www.cnblogs.com/qq1012662902/p/4019942.html