• POJ 3694 Network(双连通分量)


    http://poj.org/problem?id=3694

    题意 : N个点,M条边,构成一个连通图,将图中加入特定的一些边,每加一条边就输出加入这条边后图中剩的桥的个数。

    思路 :双连通分量,用LCA

    #include <iostream>
    #include <vector>
    #include <queue>
    #include <algorithm>
    #include <stdio.h>
    #include <string.h>
    
    using namespace std;
    
    const int maxn = 100005 ;
    const int maxm = 555555 ;
    const int INF = 1000000000 ;
    
    struct Edge
    {
        int v, next;
    }map[maxm];
    
    int low[maxn],dfn[maxn],index,vis[maxn] ;
    int e,n,m,a,b,head[maxn] ;
    int cnt,bridge[maxn],father[maxn] ;
    
    void Init()
    {
        e = 0 ; index = 0 ; cnt = 0 ;
        memset(vis,0,sizeof(vis)) ;
        memset(bridge,0,sizeof(bridge)) ;
        memset(dfn,0,sizeof(dfn)) ;
        memset(head,-1,sizeof(head)) ;
        for(int i = 1 ; i <= n ; i++)
        father[i] = i ;
    }
    
    void addedge(int v,int w)
    {
        map[e].v = w ;
        map[e].next = head[v] ;
        head[v] = e++ ;
    }
    
    void tarjan(int u)
    {
        vis[u] = 1 ;
        dfn[u] = low[u] = ++index ;
        for(int i = head[u] ; i+1 ; i = map[i].next)
        {
            int v = map[i].v ;
            if(!vis[v])
            {
                father[v] = u ;
                tarjan(v) ;
                low[u] = min(low[u],low[v]) ;
                if(low[v] > dfn[u])
                {
                    cnt++ ;
                    bridge[v] = 1 ;
                }
            }
            else if(vis[v] == 1 && v != father[u])
            low[u] = min(low[u],dfn[v]) ;
        }
        vis[u] = 2 ;
    }
    
    void lca(int u,int v)
    {
        while(dfn[u] > dfn[v])
        {
            if(bridge[u]) cnt--,bridge[u] = 0 ;
            u = father[u] ;
        }
        while(dfn[v] > dfn[u])
        {
            if(bridge[v]) cnt--,bridge[v] = 0 ;
            v = father[v] ;
        }
        while(u != v)
        {
            if(bridge[u]) cnt--,bridge[u] = 0 ;
            if(bridge[v]) cnt--,bridge[v] = 0 ;
            u = father[u] ;
            v = father[v] ;
        }
    }
    int main()
    {
    
        int kase = 0 ;
        while(scanf("%d %d",&n,&m)!=EOF)
        {
            if(n == 0 && m == 0) break ;
    
            Init() ;
            while(m--)
            {
                scanf("%d %d",&a,&b) ;
                addedge(a,b) ;
                addedge(b,a) ;
            }
            tarjan(1) ;
            int k ;
            scanf("%d",&k) ;
            printf("Case %d:
    ",++kase) ;
            while(k--)
            {
                scanf("%d %d",&a,&b) ;
                lca(a,b) ;
                printf("%d
    ",cnt) ;
            }
            printf("
    ") ;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    indexDB的用法
    append动态生成的元素,无法触发事件的原因及解决方案
    jquery中attr()和prop()的区别
    arguments.callee
    meter标签度量衡如何改变颜色
    Nginx入门
    linux中的权限管理
    python_面向对象
    ORM
    Flask入门
  • 原文地址:https://www.cnblogs.com/luyingfeng/p/3543496.html
Copyright © 2020-2023  润新知