zoukankan      html  css  js  c++  java
  • 洛谷 P3225 [HNOI2012]矿场搭建

    传送门

    题目大意:建设几个出口,使得图上无论哪个点被破坏,都可以与出口联通。

    题解:tarjian求割点

    首先出口不能建在割点上,找出割点,图就被分成了几个联通块。

    每个联通块,建出口。如果割点数为0,建两个出口,一个炸了

    另一个还可以走,那么方案数是c(size,2),如果割点为1个,那么

    随便从联通块里建一个就好,割点炸了有新建的,新建的炸了还有

    割点可以走,方案数是联通块大小。注意long long

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 5200
    #define LL long long
    using namespace std;
    
    int n,kis,sumedge,root,cnt,tim,head[maxn],low[maxn],dfn[maxn],iscut[maxn],vis[maxn];
    LL ans=1,tmp;
    int cntcut,kuai;
    
    struct Edge{
        int x,y,nxt;
        Edge(int x=0,int y=0,int nxt=0):
            x(x),y(y),nxt(nxt){}
    }edge[maxn<<1];
    
    void add(int x,int y){
        edge[++sumedge]=Edge(x,y,head[x]);
        head[x]=sumedge;
    }
    
    void Tarjian(int x,int fa){
        int cnt=0;low[x]=dfn[x]=++tim;
        for(int i=head[x];i;i=edge[i].nxt){
            int v=edge[i].y;
            if(v==fa)continue;
            if(dfn[v]==0){
                cnt++;
                Tarjian(v,x);
                low[x]=min(low[x],low[v]);
                if(x!=root&&low[v]>=dfn[x]&&iscut[x]==0)iscut[x]=true;
                if(x==root&&cnt>=2&&iscut[x]==0)iscut[x]=true;
            }else low[x]=min(low[x],dfn[v]);
        }
    }
    
    void dfs(int x){
        tmp++;vis[x]=kuai;
        for(int i=head[x];i;i=edge[i].nxt){
            int v=edge[i].y;
            if(iscut[v]&&vis[v]!=kuai)cntcut++,vis[v]=kuai;
            if(!vis[v])dfs(v);
        }
    }
    
    int main(){
        while(1){
            scanf("%d",&n);
            sumedge=0;tim=0;ans=1;cnt=0;
            kuai=0;memset(vis,0,sizeof(vis));
            memset(iscut,0,sizeof(iscut));
            memset(dfn,0,sizeof(dfn));
            memset(low,0,sizeof(low));
            memset(head,0,sizeof(head));
            if(!n)break;int xr=0;
            for(int i=1;i<=n;i++){
                int x,y;
                scanf("%d%d",&x,&y);
                add(x,y);add(y,x);
                xr=max(max(x,y),xr);
            }
            for(int i=1;i<=xr;i++)if(dfn[i]==0)root=i,Tarjian(i,i);
            for(int i=1;i<=xr;i++){
                tmp=0;cntcut=0;kuai++;
                if(vis[i]==0&&iscut[i]==0){
                    dfs(i);if(cntcut==1)cnt++,ans=1LL*ans*tmp;
                    if(cntcut==0)cnt+=2,ans=1LL*ans*tmp*(tmp-1)/2;
                }
            }
            printf("Case %d: %d %lld
    ",++kis,cnt,ans);
        }
        return 0;
    }
    AC
  • 相关阅读:
    eclipse快捷键
    ideaIU-2017.3.2版本的免费安装以及2020版本破解
    并发相关问题以及java基础知识
    飞秋软件-局域网内互传
    视频解析网站
    bzoj2458: [BeiJing2011]最小三角形
    bzoj3170: [Tjoi2013]松鼠聚会
    bzoj5056:OI游戏
    dtoj#4224. 小L的占卜
    dtoj#4222. 小b爱旅行(travel)
  • 原文地址:https://www.cnblogs.com/zzyh/p/7718912.html
Copyright © 2011-2022 走看看