poj 3694 Network

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
这个题啊!有点难度,一开始都只是想求出桥之后,再加入之后可能存在环,怎么办呢,后来才知道还有LCA这东西,当找到它们的LCA,把该路上的桥的去掉之后就是解了,那题目就简单了,求一次双连通,求一次LCA,不过我的程序跑了3000多ms,因为我求LCA是用普通的o(n)的算法,如果用o(lgn)的算法,那就不能求出答案咯,所以5000ms也真的是这个题的解法啊
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<cmath>
#include<vector>
#include<cstdio>
#include<string>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define  inf 0x0f0f0f0f
using namespace std;

struct CUT_E
{
    static const int maxn=100000+10;
    int low[maxn],pre[maxn],dfs_clock,n,m,sumcut,parent[maxn];
    bool iscut[maxn];
    vector<int>group[maxn];

    void init()
    {
        for (int i=0;i<=n;i++) {
            group[i].clear();
            pre[i]=0;
            iscut[i]=false;
            parent[i]=i;
        }
        sumcut=0; dfs_clock=0;
    }

    void addedge(int u,int v)
    {
        group[u].push_back(v);
        group[v].push_back(u);
    }

    int dfs(int u,int fa)
    {
        int lowu=pre[u]=++dfs_clock;
        for (int i=0;i<group[u].size();i++)
        {
            int v=group[u][i];
            if (!pre[v])
            {
                parent[v]=u;
                int lowv=dfs(v,u);
                lowu=min(lowu,lowv);
                if (lowv>pre[u]) {iscut[v]=true;sumcut++;}
            }
            else if (pre[v]<pre[u] && v!=fa) lowu=min(lowu,pre[v]);
        }
        low[u]=lowu;
        return lowu;
    }

    int get_sum()
    {
        int ans=dfs(-1,1);
        for (int i=1;i<=n;i++)
        for (int j=1;j<=n;j++)
        //if (cut_edge[i][j]) sumcut++;
        return sumcut;
    }
}network;

int LCA(int a,int b)
{
    if(network.pre[a]<network.pre[b]) swap(a,b);
    while (network.pre[a]>network.pre[b])
    {
        if (network.iscut[a]) {network.sumcut--;network.iscut[a]=false;}
        a=network.parent[a];
    }
    while (a!=b)
    {
        if (network.iscut[b]) {network.sumcut--;network.iscut[b]=false;}
        b=network.parent[b];
    }
    return network.sumcut;
}

int main()
{
    int x,y,q,k=0;
    while (scanf("%d%d",&network.n,&network.m)!=EOF && network.n && network.m)
    {
        k++;
        network.init();
        for (int i=0;i<network.m;i++)
        {
            scanf("%d%d",&x,&y);
            network.addedge(x,y);
        }
        network.dfs(1,-1);
        scanf("%d",&q);
        printf("Case %d:
",k);
        while (q--)
        {
            scanf("%d%d",&x,&y);
            int ans=LCA(x,y);
            printf("%d
",ans);
        }
    }
    return 0;
}
至少做到我努力了
原文地址:https://www.cnblogs.com/chensunrise/p/3739684.html