zoukankan      html  css  js  c++  java
  • 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;
    }
    至少做到我努力了
  • 相关阅读:
    解决GitHub下载速度太慢的问题
    java监测硬盘空间大小
    @SuppressWarnings注解用法详解
    No goals have been specified for this build.
    java新建excel文件导出(HSSFWorkbook)
    mysql日志文件路径
    获取select框下option所有值
    jquery获取select选中的值
    mysql查看查询缓存是否启用
    Kafka消息重新发送
  • 原文地址:https://www.cnblogs.com/chensunrise/p/3739684.html
Copyright © 2011-2022 走看看