POJ3694(桥+LCA)

版权声明:本人蒟蒻,如有大佬转发,感激不尽,带上我的博客链接即可。 https://blog.csdn.net/qq_36300700/article/details/81867558

借鉴了一位大佬的博客:https://blog.csdn.net/sdj222555/article/details/7211644

题意:一个网络管理员管理一个网络,网络中的电脑直接或间接的相连接,管理员有Q次操作,每次向网络中建立一条新边,向管理员报告桥的个数。(输入保证强连通)

分析:这题的大概思路就是,先求割边并标记,然后缩点,形成一棵树,然后把这颗树上各个结点的父结点用dfs求出来,再然后就是LCA了,因为加入某条边后,树内会形成一个圈,这个圈上所有的边将不再是桥,可以发现跟LCA的关联。

代码:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <vector>
#include <map>
#include <stack>
#include <queue>

using namespace std;
const int maxn =100000+5;

int N,M,Q;
int low[maxn],pre[maxn],dfn[maxn],fa[maxn],iscut[maxn],dfs_clock,cnt,k=1;
vector<int>G[maxn];

void init()
{
    for(int i=1; i<=N; i++)
        {
            G[i].clear();
            fa[i]=i;
        }
    memset(iscut,0,sizeof(iscut));
    memset(pre,0,sizeof(pre));
    memset(dfn,0,sizeof(dfn));

    cnt=dfs_clock=0;

}

int dfs(int u)
{
    dfn[u]=dfn[fa[u]]+1;
    int lowu = pre[u] = ++dfs_clock;

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

void ask()
{
    printf("Case %d:\n",k++);
    scanf("%d",&Q);
    while(Q--)
    {
        int A,B;
        scanf("%d %d",&A,&B);

        while(dfn[A]>dfn[B])
        {
            if(iscut[A])
            {
                iscut[A]=0;
                cnt--;
            }
            A=fa[A];
        }

        while(dfn[B]>dfn[A])
        {
            if(iscut[B])
            {
                iscut[B]=0;
                cnt--;
            }
            B=fa[B];
        }
        while(A!=B)
        {
            if(iscut[A])
            {
                iscut[A]=0;
                cnt--;
            }
            if(iscut[B])
            {
                iscut[B]=0;
                cnt--;
            }
            A=fa[A],B=fa[B];
        }
        printf("%d\n",cnt);
    }
    printf("\n");
}



int main()
{
     while(scanf("%d %d",&N,&M)&&(N+M))
     {
         init();
         int u,v;
         for(int i=1; i<=M; i++)
         {
             scanf("%d %d",&u,&v);
             G[u].push_back(v);
             G[v].push_back(u);

         }
             dfs(1);
             ask();
     }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_36300700/article/details/81867558