zoukankan      html  css  js  c++  java
  • poj2117 Electricity

     
    试题描述
    求一个图删除一个点之后,联通块最多有多少。
    输入
    多组数据。第一行两个整数 P,C 表示点数和边数。
    接下来 C 行每行两个整数 p1,p2,表示 p1 与 p2 有边连接,保证无重边。读入以 0 0 结束。
    输出
    输出若干行,表示每组数据的结果。
    输入示例
    3 3
    0 1
    0 2
    2 1
    4 2
    0 1
    2 3
    3 1
    1 0
    0 0
    输出示例
    1
    2
    2

    详解参考https://blog.csdn.net/u013480600/article/details/30976823。

    在dfs的时候,我们用cut[i]==X表示在dfs树中当i节点被删除时,i节点的X个儿子被切割开来(可以认为cut[i]是i节点与它的儿子连接的桥边的数目)。注意:如果i是根且其儿子只有1个,虽然i不是割点,cut[i]依然=1。如果i节点非割点,那么cut[i]=0。如果i是割点,那么cut[i]就是i被删除后将割出来的儿子数目。

           然后我们求出了每个点的cut[i]值,即i点被删除,会有cut[i]个儿子树被割出来。如果i是dfs树的非根节点,那么cut[i]== 切除i之后增加的连通分量数目。如果i是dfs树的根节点,那么cut[i]-1才是切除i之后增加的连通分量数目(想想是不是)。

            如果原始cut[i]=0,表示i是孤立的一点,此时cut[i]-1=-1.

            如果原始cut[i]=1,表示i为根且有一个儿子,此时cut[i]-1=0.

            如果原始cut[i]>=2,表示i为根且分割了>=2个儿子,此时cut[i]-1>=1.

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cstdlib>
    #define MAXN 100010
    #define REP(i,k,n) for(int i=k;i<=n;i++)
    #define in(a) a=read()
    using namespace std;
    inline int read(){
        int f=1,x=0;
        char ch=getchar();
        for(;!isdigit(ch);ch=getchar())
            if(ch=='-')
                f=-1;
        for(;isdigit(ch);ch=getchar())
            x=x*10+ch-'0';
        return x*f;
    }
    int n,m,cnt,ans;
    int total=0,head[MAXN],to[MAXN<<2],nxt[MAXN<<2];
    int dfn[MAXN],low[MAXN],sum[MAXN];
    inline void adl(int a,int b){
        total++;
        to[total]=b;
        nxt[total]=head[a];
        head[a]=total;
        return ;
    }
    inline void tarjan(int u,int f){
        low[u]=dfn[u]=++cnt;
        for(int e=head[u];e;e=nxt[e]){
            if(!dfn[to[e]]){
                tarjan(to[e],u);
                low[u]=min(low[to[e]],low[u]);
                if(low[to[e]]>=dfn[u]) sum[u]++;
            }
            else if(to[e]!=f)  low[u]=min(low[u],dfn[to[e]]);
        } 
        return ;
    }
    int main(){
        while(scanf("%d%d",&n,&m)){
            if(n==0 && m==0)  return 0;
            int a,b;
            total=cnt=ans=0;
            memset(head,0,sizeof(head));
            memset(dfn,0,sizeof(head));
            memset(low,0,sizeof(low));
            memset(sum,0,sizeof(sum));
            REP(i,1,m){
                in(a);in(b);
                adl(a,b);
                adl(b,a);    
            }
            int num=0;
            ans=-10000;
            REP(i,0,n-1)
                if(!dfn[i]){
                    num++; 
                    tarjan(i,-1);
                    sum[i]--;
                }
            REP(i,0,n-1) ans=max(ans,sum[i]);
            cout<<ans+num<<endl;
        }
        return 0;
    }
  • 相关阅读:
    描述软件质量属性需求和质量属性场景(以淘宝网为例)
    软件架构初识
    机器学习实践02
    机器学习实践01
    机器学习十讲02
    用户故事与敏捷方法阅读笔记05
    机器学习十讲01
    用户故事与敏捷方法阅读笔记04
    tensorflow学习05(Mnist数据集)
    spring boot发送HTTP请求
  • 原文地址:https://www.cnblogs.com/jason2003/p/9706346.html
Copyright © 2011-2022 走看看