• UVA-10765 Doves and bombs (双连通分量)


    题目大意:给一个n个点的无向连通图,找出删除某个点后的连通块个数。

    题目分析:统计一下每个节点属于几个双连通分量,若是割点,得到的便是答案,否则答案为1。

    代码如下:

    # include<iostream>
    # include<cstdio>
    # include<stack>
    # include<vector>
    # include<cstring>
    # include<algorithm>
    using namespace std;
    # define REP(i,s,n) for(int i=s;i<n;++i)
    # define CL(a,b) memset(a,b,sizeof(a));
    
    const int N=10005;
    struct Edge
    {
        int u,v;
        Edge(int _u,int _v):u(_u),v(_v){}
        bool operator < (const Edge &a) const {
            if(v==a.v)  return u<a.u;
            return v>a.v;
        }
    };
    stack<Edge>S;
    vector<Edge>ans;
    vector<int>G[N],bcc[N];
    int n,m,dfs_cnt,bcc_cnt,bccno[N],pre[N],low[N],cnt[N],iscut[N];
    
    void dfs(int u,int fa)
    {
        low[u]=pre[u]=++dfs_cnt;
        int child=0;
        REP(i,0,G[u].size()){
            int v=G[u][i];
            if(pre[v]==0){
                ++child;
                S.push(Edge(u,v));
                dfs(v,u);
                low[u]=min(low[u],low[v]);
                if(low[v]>=pre[u]){
                    iscut[u]=1;
                    bcc[++bcc_cnt].clear();
                    while(1){
                        Edge x=S.top();
                        S.pop();
                        if(bccno[x.u]!=bcc_cnt){
                            bcc[bcc_cnt].push_back(x.u);
                            bccno[x.u]=bcc_cnt;
                        }if(bccno[x.v]!=bcc_cnt){
                            bcc[bcc_cnt].push_back(x.v);
                            bccno[x.v]=bcc_cnt;
                        }
                        if(x.u==u&&x.v==v) break;
                    }
                }
            }else if(pre[v]<pre[u]&&v!=fa){
                S.push(Edge(u,v));
                low[u]=min(low[u],pre[v]);
            }
        }
        if(fa<0&&child==1) iscut[u]=0;
    }
    
    void findBcc()
    {
        CL(bccno,0);
        CL(iscut,0);
        CL(pre,0);
        dfs_cnt=bcc_cnt=0;
        REP(i,0,n) if(!pre[i])
            dfs(i,-1);
    }
    
    int main()
    {
        int a,b;
        while(scanf("%d%d",&n,&m)&&(n+m))
        {
            REP(i,0,n) G[i].clear();
            while(scanf("%d%d",&a,&b))
            {
                if(a==-1&&b==-1)
                    break;
                G[a].push_back(b);
                G[b].push_back(a);
            }
            findBcc();
            ans.clear();
            CL(cnt,0);
            REP(i,1,bcc_cnt+1) REP(j,0,bcc[i].size()) ++cnt[bcc[i][j]];
            REP(i,0,n){
                if(iscut[i])
                    ans.push_back(Edge(i,cnt[i]));
                else
                    ans.push_back(Edge(i,1));
            }
            sort(ans.begin(),ans.end());
            REP(i,0,m) printf("%d %d
    ",ans[i].u,ans[i].v);
            printf("
    ");
        }
        return 0;
    }
    

      

  • 相关阅读:
    [置顶] cocos2dx sqllite 增删查改等操作
    BZOJ 2933([Poi1999]地图-区间Dp)
    java使用batik转换svg文件
    算法小题目小结。。。
    [置顶] shell变量赋值-linux
    高级IO复用应用:聊天室程序
    NSUserDefaults的使用
    动态链接库与静态链接库的区别
    阐明iOS证书和provision文件
    Hyperic Agent 安装配置报
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/4923169.html
Copyright © 2020-2023  润新知