D - Network - poj3694(LCA求橋)


題意:有一個網絡有一些邊相互連接,現在有Q次操作,求每次操作后的橋的個數
分析:開始竟然不知道還有LCA這么個東西.......
*****************************************************************
#include<stdio.h>
#include< string.h>
#include<algorithm>
using  namespace std;

const  int MAXN = 1e5+ 5;

/* *******添加邊************ */
struct Edage{ int v, next, used;}e[MAXN<< 2];
int Head[MAXN], cnt;
void AddEdge( int u,  int v)
{
    e[cnt].v = v;
    e[cnt].next = Head[u];
    e[cnt].used =  false;
    Head[u] = cnt++;
}
/* **********Tarjan算法變量********* */
int dfn[MAXN], low[MAXN], Index;
int fa[MAXN];
int isbridge[MAXN], nbridge;

void InIt( int N)
{
    cnt = Index = nbridge =  0;

     for( int i= 0; i<=N; i++)
    {
        Head[i] = - 1;
        dfn[i] =  0;
        isbridge[i] =  false;
    }
}
void Tarjan( int u,  int father)
{
     int v;

    low[u] = dfn[u] = ++Index;
    fa[u] = father;

     for( int j=Head[u]; j!=- 1; j=e[j].next)
    {
         if(e[j].used ==  false)
        {
            e[j].used = e[j^ 1].used =  true;
            v = e[j].v;
             if( !dfn[v] )
            {
                Tarjan(v, u);
                low[u] = min(low[u], low[v]);

                 if( low[v] > dfn[u] )
                {
                    isbridge[v] =  true;
                    nbridge++;
                }
            }
             else
                low[u] = min(low[u], dfn[v]);
        }
    }
}

void LCA( int u,  int v)
{
     if(dfn[u] < dfn[v])
        swap(u, v);

     while(dfn[u] > dfn[v])
    {
         if(isbridge[u])nbridge--;
        isbridge[u] =  false;
        u = fa[u];
    }

     while(u != v)
    {
         if(isbridge[u])nbridge--;
         if(isbridge[v])nbridge--;
        isbridge[u] = isbridge[v] =  false;

        u = fa[u], v = fa[v];
    }
}

int main()
{
     int N, M, t= 1;

     while(scanf( " %d%d ", &N, &M), N+M)
    {
         int u, v;

        InIt(N);

         while(M--)
        {
            scanf( " %d%d ", &u, &v);
            AddEdge(u, v);
            AddEdge(v, u);
        }

        Tarjan( 11);

        scanf( " %d ", &M);

        printf( " Case %d:\n ", t++);
         while(M--)
        {
            scanf( " %d%d ", &u, &v);
            LCA(u, v);
            printf( " %d\n ", nbridge);
        }

        printf( " \n ");
    }

     return  0;  

}

 


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
  © 2014-2022 ITdaan.com 联系我们: