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
  • 相关阅读:
    nginx各版本全自动编译安装脚本
    kubernetes里面有时候centos源用不了
    centons6升级gcc和glibc版本
    容器下载的是centos8的镜像,scp出现packet_write_wait: Connection to **** port 22: Broken pipe 问题解决
    MNIST数据集手写体识别(MLP实现)
    BP 算法手动实现
    Python直接调用C库的printf()函数打印一条消息
    C/C++与Python实现混编(详细注释)
    MNIST数据集手写体数据还原为图片
    TensorFlow初识(MNIST数据集识别手写体)
  • 原文地址:https://www.cnblogs.com/xkui/p/4550746.html
Copyright © 2011-2022 走看看