码迷,mamicode.com
首页 > 其他好文 > 详细

洛谷 P3225 [HNOI2012]矿场搭建

时间:2017-10-23 21:50:38      阅读:248      评论:0      收藏:0      [点我收藏+]

标签:fine   hid   www.   col   bsp   src   none   sizeof   eof   

传送门

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

题解: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\n",++kis,cnt,ans);
    }
    return 0;
}
AC

 

洛谷 P3225 [HNOI2012]矿场搭建

标签:fine   hid   www.   col   bsp   src   none   sizeof   eof   

原文地址:http://www.cnblogs.com/zzyh/p/7718912.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!