zoukankan      html  css  js  c++  java
  • 【双连通分量】Bzoj2730 HNOI2012 矿场搭建

    Description

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

    Sulotion

    坍塌的不是割顶并不影响,建在割顶也没有意义(拆割顶)

    考虑每一个双连通分量,如果只连一个割顶必须内部建一个(随便选一个),连两个以上可以不用建(一个割顶坍塌还可以走另一个)

    特殊情况是,如果无割顶建两个

    并不需要求出双连通分量,把割顶求出删掉,dfs处理时统计即可

    说起来这道题也是WF2011,HNOI竟然考原题。。

    Code

    一开始一直WA,copy标程大力对拍,结果是特殊情况忘输出case...范逗

    接着拍,还是不对,调半天搞出一组小数据,然后发现标程错了...世界再见...这种事情以前就出现过一次...所以还是要自己老老实实写暴力对拍?

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<vector>
     4 #include<cstring>
     5 using namespace std;
     6 const int maxn=505;
     7 
     8 int pre[maxn],low[maxn],iscut[maxn],bcc[maxn];
     9 int clock,cnt,size[maxn],t[maxn],vis[maxn];
    10 vector<int>e[maxn];
    11 int n,m;
    12 
    13 int clear(){
    14     memset(pre,0,sizeof(pre));
    15     memset(low,0,sizeof(low));
    16     memset(iscut,0,sizeof(iscut));
    17     memset(bcc,0,sizeof(bcc));
    18     memset(size,0,sizeof(size));
    19     memset(t,0,sizeof(t));
    20     memset(vis,0,sizeof(vis));
    21     for(int i=0;i<maxn;i++) e[i].clear();
    22     clock=cnt=n=0;
    23 }
    24 
    25 int getcut(int p,int u){
    26     pre[u]=low[u]=++clock;
    27     int child=0;
    28     for(int i=0;i<e[u].size();i++){
    29         int v=e[u][i];
    30         if(!pre[v]){
    31             child++;
    32             getcut(u,v);
    33             low[u]=min(low[u],low[v]);
    34             if(low[v]>=pre[u]){
    35                 iscut[u]=1;
    36             }
    37         }
    38         else if(pre[v]<pre[u]&&v!=p){
    39             low[u]=min(low[u],pre[v]);
    40         }
    41     }
    42     if(p==0&&child==1) iscut[u]=0;
    43 }
    44 
    45 int dfs(int u){
    46     vis[u]=cnt,size[cnt]++;
    47     for(int i=0;i<e[u].size();i++){
    48         int v=e[u][i];
    49         if(vis[v]) continue;
    50         if(!iscut[v]) dfs(v);
    51         else {
    52             if(bcc[v]!=cnt)
    53                 bcc[v]=cnt,t[cnt]++;
    54         }
    55     }
    56 }
    57 
    58 int main(){
    59     //freopen("2730.in","r",stdin);
    60     //freopen("2730a.out","w",stdout);
    61     
    62     int time=0;
    63     while(scanf("%d",&m)==1&&m){
    64         clear();
    65         int u,v;
    66         
    67         for(int i=1;i<=m;i++){
    68             scanf("%d%d",&u,&v);
    69             e[u].push_back(v);
    70             e[v].push_back(u);
    71             n=max(n,max(u,v));
    72         }
    73         
    74         for(int i=1;i<=n;i++)
    75             if(!pre[i]) getcut(0,i);
    76             
    77         for(int i=1;i<=n;i++)
    78             if(!iscut[i]&&!vis[i]){
    79                 ++cnt;
    80                 dfs(i);
    81             }
    82             
    83         if(cnt==1){
    84             printf("Case %d: 2 %d
    ",++time,n*(n-1)/2);
    85             continue;
    86         }
    87             
    88         long long tot=0,ans=1;
    89         for(int i=1;i<=cnt;i++)
    90             if(t[i]==1) tot++,ans*=size[i];
    91         printf("Case %d: %lld %lld
    ",++time,tot,ans);
    92     }
    93 }
    View Code
  • 相关阅读:
    记录cacti时间筛选bug的解决办法
    mysql开启远程访问权限
    Mysql 5.7.32 安装cacti-0.8.8h出错
    记录Apache无法解析PHP代码解决方法
    zabbix5.0安装问题:Time zone for PHP is not set
    数据库以及数据表的创建
    小程序框架wepy
    通用的代码总结
    html网页什么样的字体最好看,css设置各种中文字体样式代码
    vue中使用BetterScroll(网上)
  • 原文地址:https://www.cnblogs.com/xkui/p/4550746.html
Copyright © 2011-2022 走看看