zoukankan      html  css  js  c++  java
  • 【BZOJ 2730】 [HNOI2012]矿场搭建

    Description

    煤矿工地可以看成是由隧道连接挖煤点组成的无向图。为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处。于是矿主决定在某些挖煤点设立救援出口,使得无论哪一个挖煤点坍塌之后,其他挖煤点的工人都有一条道路通向救援出口。请写一个程序,用来计算至少需要设置几个救援出口,以及不同最少救援出口的设置方案总数。

    Input

    输入文件有若干组数据,每组数据的第一行是一个正整数 N(N≤500),表示工地的隧道数,接下来的 N 行每行是用空格隔开的两个整数 S 和 T,表示挖       S 与挖煤点 T 由隧道直接连接。输入数据以 0 结尾。

    Output

    输入文件中有多少组数据,输出文件 output.txt 中就有多少行。每行对应一组输入数据的 结果。其中第 i 行以 Case i: 开始(注意大小写,Case 与 i 之间有空格,i 与:之间无空格,: 之后有空格),其后是用空格隔开的两个正整数,第一个正整数表示对于第 i 组输入数据至少需 要设置几个救援出口,第二个正整数表示对于第 i 组输入数据不同最少救援出口的设置方案总 数。输入数据保证答案小于 2^64。输出格式参照以下输入输出样例。

    Sample Input

    9
    1 3
    4 1
    3 5
    1 2
    2 6
    1 5
    6 3
    1 6
    3 2
    6
    1 2
    1 3
    2 4
    2 5
    3 6
    3 7
    0

    Sample Output

    Case 1: 2 4
    Case 2: 4 1

    HINT

    Case 1 的四组解分别是(2,4),(3,4),(4,5),(4,6);

    Case 2 的一组解为(4,5,6,7)。
     
    寻找图上的割点
    不要在割点建安全点
    如果图上没有割点则答案为C(n,2)
    删掉割点跑联通性
    如果一个联通块内有两个及以上割点就不用建,塌了一个还可以跑去别的地方
    有一个割点就要建一个,不要建在割点
     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 using namespace std;
     5 const int N=510;
     6 struct ee{int to,next;}e[N*N];
     7 int head[N],dfn[N],low[N],size[N],sum[N];
     8 bool cut[N],vis[N],vis1[N];
     9 int cnt,n,sz,T,m,timer;
    10 long long num,ans;
    11 void ins(int u,int v){
    12     e[++cnt].to=v,e[cnt].next=head[u],head[u]=cnt;
    13     e[++cnt].to=u,e[cnt].next=head[v],head[v]=cnt;
    14 }
    15 int tarjan(int u,int fa){
    16     int child=0,lowu;
    17     lowu=dfn[u]=low[u]=++timer;
    18     for (int i=head[u];i;i=e[i].next){
    19         int v=e[i].to;
    20         if(!dfn[v]){
    21             child++;
    22             int lowv=tarjan(v,u);
    23             lowu=min(lowu,lowv);
    24             if (lowv>=dfn[u]) cut[u]=1;  
    25         }
    26         else if(dfn[v]<dfn[u]&&v!=fa)
    27             lowu=min(lowu,dfn[v]);
    28     }
    29     if(fa<0&&child==1) cut[u]=0;
    30     low[u]=lowu;
    31     return lowu;
    32 }
    33  
    34 void dfs(int x,int sz){
    35     vis[x]=1;size[sz]++;
    36     for (int i=head[x];i;i=e[i].next){
    37         int v=e[i].to;
    38         if(!vis[v]&&!cut[v]){
    39             dfs(v,sz);
    40         }else{
    41             if (cut[v]&&!vis1[v]) sum[sz]++,vis1[v]=1;
    42         }
    43     }
    44 }
    45  
    46 int main(){
    47     while(1){
    48         scanf("%d",&m);
    49         if(m==0) break;
    50         cnt=n=sz=timer=num=0;ans=1;
    51         memset(head,0,sizeof(head));
    52         memset(e,0,sizeof(e));
    53         memset(cut,0,sizeof(cut));
    54         memset(vis,0,sizeof(vis));
    55         memset(low,0,sizeof(low));
    56         memset(dfn,0,sizeof(dfn));
    57         memset(sum,0,sizeof(sum));
    58         memset(size,0,sizeof(size));
    59         T++;printf("Case %d: ",T);
    60         int u,v;
    61         for(int i=1;i<=m;i++){
    62             scanf("%d%d",&u,&v);
    63             n=max(n,u),n=max(n,v);
    64             ins(u,v);
    65         }
    66         tarjan(1,-1);
    67         for(int i=1;i<=n;i++) if(!cut[i]&&!vis[i]) {
    68             memset(vis1,0,sizeof(vis1));
    69             dfs(i,++sz);
    70         }
    71         if(sz==1) ans=(n-1)*n/2,num=2;
    72         else{
    73             for (int i=1;i<=sz;i++){
    74                 if(sum[i]==1)ans*=size[i],num++;
    75             }
    76         }
    77         printf("%lld %lld
    ",num,ans);
    78     }
    79 }
  • 相关阅读:
    css 权威指南笔记
    angular directive restrict 的用法
    vim 的寄存器
    以普通用户启动的Vim如何保存需要root权限的文件
    jshint options
    如何在Ubuntu Linux上安装Oracle Java
    Linux:使用nohup让进程在后台可靠运行
    反射-----学习Spring必学的Java基础知识之一
    java异常捕获
    cookie
  • 原文地址:https://www.cnblogs.com/wuminyan/p/5194204.html
Copyright © 2011-2022 走看看