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

    https://www.luogu.org/problem/show?pid=3225

    题目描述

    煤矿工地可以看成是由隧道连接挖煤点组成的无向图。为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处。于是矿主决定在某些挖煤点设立救援出口,使得无论哪一个挖煤点坍塌之后,其他挖煤点的工人都有一条道路通向救援出口。

    请写一个程序,用来计算至少需要设置几个救援出口,以及不同最少救援出口的设置方案总数。

    输入输出格式

    输入格式:

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

    输出格式:

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

    输入输出样例

    输入样例#1:
    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
    输出样例#1:
    Case 1: 2 4
    Case 2: 4 1

    说明

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

    Case 2 的一组解为(4,5,6,7)。

    很明显需要求出割点。屏蔽割点后、

    ①若一个双联通中没有割点,那么最少需要两个出口(炸了一个去另一个)

    ②若一个双联通能连到一个割点,那么最少需要在双联通中设置一个出口,炸了割点还能逃生、

    ③若一个双联通能连到多余一个割点,那么不管怎么炸,都能从没炸的割点跑到别的分量里

     1 #include <cstring>
     2 #include <cstdio>
     3 
     4 const int N(555);
     5 int head[N],sumedge=1;
     6 struct Edge
     7 {
     8     int v,next;
     9     Edge(int v=0,int next=0):v(v),next(next){}
    10 }edge[N*N/2];
    11 inline void ins(int u,int v)
    12 {
    13     edge[++sumedge]=Edge(v,head[u]);
    14     head[u]=sumedge;
    15     edge[++sumedge]=Edge(u,head[v]);
    16     head[v]=sumedge;
    17 }
    18 
    19 #define max(a,b) (a>b?a:b)
    20 #define min(a,b) (a<b?a:b)
    21 int tim,dfn[N],low[N];
    22 int cutpoint[N];
    23 void Tarjan(int u,int pre)
    24 {
    25     dfn[u]=low[u]=++tim;
    26     int sumtredge=0,if_point=0;
    27     for(int v,i=head[u];i;i=edge[i].next)
    28     {
    29         v=edge[i].v;
    30         if((i^1)==pre) continue;
    31         if(!dfn[v])
    32         {
    33             sumtredge++;
    34             Tarjan(v,i);
    35             if(low[v]>=dfn[u]) if_point=1;
    36             low[u]=min(low[u],low[v]);
    37         }
    38         else low[u]=min(low[u],dfn[v]);
    39     }
    40     if(!pre)
    41     {
    42         if(sumtredge>1) cutpoint[u]=1;
    43     }
    44     else if(if_point) cutpoint[u]=1;
    45 }
    46 
    47 int sumcol,point,cnt,vis[N],col[N];
    48 void DFS(int u)
    49 {
    50     point++;
    51     vis[u]=1;
    52     col[u]=sumcol;
    53     for(int v,i=head[u];i;i=edge[i].next)
    54     {
    55         v=edge[i].v;
    56         if(cutpoint[v]&&col[v]!=sumcol) cnt++,col[v]=sumcol;
    57         if(!vis[v]&&!cutpoint[v]) DFS(v);
    58     }
    59 }
    60 
    61 inline void init()
    62 {
    63     tim=sumcol=0; sumedge=1;
    64     memset(dfn,0,sizeof(dfn));
    65     memset(col,0,sizeof(col));
    66     memset(vis,0,sizeof(vis));
    67     memset(low,0,sizeof(low));
    68     memset(head,0,sizeof(head));
    69     memset(edge,0,sizeof(edge));
    70     memset(cutpoint,0,sizeof(cutpoint));
    71 }
    72 
    73 int main()
    74 {
    75     for(int m,n=0,k=1;scanf("%d",&m)&&m;k++,n=0,init())
    76     {
    77         for(int u,v;m--;ins(u,v))
    78             scanf("%d%d",&u,&v),n=max(n,max(u,v));
    79         for(int i=1;i<=n;i++)
    80             if(!dfn[i]) Tarjan(i,0);
    81         long long ans_sum=1;
    82         int ans_cnt=0;
    83         for(int i=1;i<=n;i++)
    84         {
    85             if(vis[i]||cutpoint[i]) continue;
    86             point=cnt=0;
    87             sumcol++,DFS(i);
    88             if(!cnt) ans_cnt+=2,ans_sum*=(long long)(point*(point-1)>>1);
    89             if(cnt==1) ans_cnt++,ans_sum*=(long long)point;
    90         }
    91         printf("Case %d: %d %lld
    ",k,ans_cnt,ans_sum);
    92     }
    93     return 0;
    94 }
    ——每当你想要放弃的时候,就想想是为了什么才一路坚持到现在。
  • 相关阅读:
    Context Menu on DataGrid
    DataGrid Column Group (合并表头)
    DataGrid loadData loadFilter
    sharepoint 2010 FieldLookup 的更新方法
    SharePoint 2010 列表查阅项栏的formfield控件对象取值
    sharepoint2010的几个类型字段赋值和取值的方法
    SharePoint 和 Windows Phone 7 开发人员培训资源
    如何提升SharePoint 2010的性能
    sharepoint国内网站一览表(转发)
    sharepoint2010列表的分页实现迅雷样式效果
  • 原文地址:https://www.cnblogs.com/Shy-key/p/7465007.html
Copyright © 2011-2022 走看看