zoukankan      html  css  js  c++  java
  • 边双联通分量

    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define maxn 1005
    #define maxm 1000005
    
    using namespace std;
    
    struct Edge{
        int u,v;
        Edge(int u=0,int v=0):u(u),v(v){}
    }e[maxm];
    int n,m,stamp,dfn[maxn],low[maxn],bccno[maxn],bcc_cnt;
    vector<int> vec[maxn];
    bool isbridge[maxm];
    
    void tarjan(int index,int fa)
    {
        int tmp;
        dfn[index]=low[index]=++stamp;
        for(int i=0;i<vec[index].size();i++)
        {
            tmp=e[vec[index][i]].v;
            if(!dfn[tmp])
            {
                tarjan(tmp,index);
                low[index]=min(low[index],low[tmp]);
                if(low[tmp]>dfn[index])
                    isbridge[vec[index][i]]=isbridge[vec[index][i]^1]=1;
            }
            else if(dfn[tmp]<dfn[index] && tmp!=fa)
            {
                low[index]=min(low[index], dfn[tmp]);
            }
        }
    }
    
    void dfs(int index)
    {
        dfn[index]=1;
        bccno[index]=bcc_cnt;
        for(int i=0;i<vec[index].size();i++)
        {
            int tmp=vec[index][i];
            if(isbridge[tmp])
                continue;
            if(!dfn[e[tmp].v])
            {
                dfs(e[tmp].v);
            }
        }
    }
    
    void find_ebcc(){
        bcc_cnt=stamp=0;
        memset(dfn,0,sizeof(dfn));
        memset(low,0,sizeof(low));
        memset(bccno,0,sizeof(bccno));
        memset(isbridge,0,sizeof(isbridge));
        for(int i=1;i<=n;i++)
            if(!dfn[i])
                tarjan(i, -1);
        memset(dfn,0,sizeof(dfn));
        for(int i=1;i<=n;i++)
        {
            if(!dfn[i])
            {
                bcc_cnt++;
                dfs(i);
            }
        }               
    }
    
    int main()
    {
        while(~scanf("%d %d",&n,&m))
        {
            memset(vec,0,sizeof(vec));
            int x,y;
            for(int i=0;i<m;i++)
            {
                scanf("%d %d",&x,&y);
                e[i*2]=Edge(x,y);
                vec[x].push_back(2*i);
                e[i*2+1]=Edge(y,x);
                vec[y].push_back(2*i+1);
            }
            find_ebcc();
    
            if(bcc_cnt==1)
                printf("0
    ");
            else
            {
                memset(dfn,0,sizeof(dfn));
                for(int i=0;i<m*2;i+=2)
                {
                    x=e[i].u, y=e[i].v;
                    if(bccno[x]!=bccno[y])
                    {
                        dfn[bccno[x]]++;
                        dfn[bccno[y]]++;
                    }
                }
    
                int a=0,b=0;
                for(int i=1;i<=bcc_cnt;i++)
                {
                    if(dfn[i]==0)
                        a++;
                    if(dfn[i]==1)
                        b++;
                }
    
                printf("%d
    ",a+(b+1)/2);           
            }
        }
    
        return 0;
    }
  • 相关阅读:
    hdu-1698(线段树,区间修改)
    hdu-1394(线段树)
    hdu-1166(线段树)
    hdu-1251(string+map)
    hdu-1711(kmp算法)
    hdu-2191(完全背包+二进制优化模板)
    hdu-2844(完全背包+二进制优化模板)
    hdu-1171(多重背包+二进制优化)
    SpringMVC 参数中接收数组、List写法
    如何高效的查询数组中是否包含某个值
  • 原文地址:https://www.cnblogs.com/lmjer/p/8324770.html
Copyright © 2011-2022 走看看