zoukankan      html  css  js  c++  java
  • poj 2117 去掉割点可以分得的联通图的个数模板

    #include<stdio.h>
    #include<string.h>
    #define N  11000
    /*
    去掉一个割点后,询问可以分得的联通图的个数
    */
    struct node {
    int u,v,next;
    }bian[N*100];
    /*cut数组记录去掉某个节点后可以增加的联通分支的个数,num数组记录以i为根节点的联通图的元素的个数*/
    int head[N],n,yong,cou,index,dfn[N],low[N],cut[N],num[N];
    void init() {
    yong=0;index=0;cou=0;
    memset(head,-1,sizeof(head));
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(num,0,sizeof(num));
    memset(cut,0,sizeof(cut));
    }
    int Min(int a,int b) {
    return a>b?b:a;
    }
    void addedge(int u,int v) {
    bian[yong].u=u;
    bian[yong].v=v;
    bian[yong].next=head[u];
    head[u]=yong++;
    }
    void tarjan(int u,int pre) {
    int i;
    dfn[u]=low[u]=++index;
    cou++;
    if(pre<0)//根节点去掉后无影响,或则单个孤立节点的计算标记
        cut[u]--;
    for(i=head[u];i!=-1;i=bian[i].next) {
        int v=bian[i].v;
        if(!dfn[v]) {
            tarjan(v,u);
            low[u]=Min(low[u],low[v]);
            if(low[v]>=dfn[u])//割点去掉后可增加联通分量
                cut[u]++;
        }
        else
            low[u]=Min(low[u],dfn[v]);
    }
    }
    int main(){
       int m,a,b,i,flag,ans,sum;
       while(scanf("%d%d",&n,&m),n||m) {
            init();
        while(m--) {
            scanf("%d%d",&a,&b);
            a++;b++;
            addedge(a,b);
            addedge(b,a);
        }
        sum=0;
        for(i=1;i<=n;i++)
        if(!dfn[i]) {
            cou=0;
            sum++;//记录有多少个联通块
            tarjan(i,-1);
            num[i]=cou;//记录以i为根节点的联通分量的元素的个数
        }
        int flag=-1;
       ans=0;
       for(i=1;i<=n;i++)
        if(cut[i]) {//只判断有影响的点包括割点,单独孤立的点等
            if(ans<cut[i]+1) {//计算可以增加的联通分量
                flag=i;
                ans=cut[i]+1;
            }
        }
        if(flag==-1) {//如果不能增加,如全部是孤立的节点,或者双联通这样的特殊情况
            flag=0;
            for(i=1;i<=n;i++)
                if(num[i]>1)//是否双联通这种情况,去掉任意一个不影响结果
                flag++;
                if(flag)
                    printf("%d
    ",sum);
                else
                    printf("%d
    ",sum-1);//说明全部都是孤立的点
        }
        else
            printf("%d
    ",ans+sum-1);
       }
    return 0;
    }
    

  • 相关阅读:
    [转载]TFS测试管理
    [转载]TFS发送邮件提醒功能
    [转载]TFS与Project、Excel同步
    [转载]TFS源代码管理8大注意事项
    [转载]TFS源代码管理
    [转载]项目风险管理七种武器之结语
    [转载]项目风险管理七种武器-拳头
    刷新SqlServer所有视图元数据的存储过程
    MSSQL 触发器 暂停 和 启动
    给 Easyui Datagrid 扩展方法
  • 原文地址:https://www.cnblogs.com/thefirstfeeling/p/4410683.html
Copyright © 2011-2022 走看看