• 2017.8.11 [HNOI2012]矿场搭建


    【题目描述】

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

    【输入格式】

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

    【输出格式】

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

    【样例输入】

     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 

    【样例输出】

    Case 1: 2 4

    Case 2: 4 1

    【提示】

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

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

    【来源】

    【题目来源】

    耒阳大世界(衡阳八中) OJ 2730

    solution

    不看题解真是快做不出题了......

    先tarjan求出所有的割点,割点会将整个连通图分成几部分

    然后给这几部分染色,染到两遍以上就说明有两个其他的部分都可以到达这部分,一个矿塌陷无影响,所以只需要在其他两部分放救援出口

    而只染过一遍的就必须放了

    特别地:如果这个图是点双联通分量(即没有割点),就只需要放一个救援出口,方案是C(n,2)=n*(n-1)/2

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<iostream>
      4 #define ll long long
      5 #define mem(a,b) memset(a,b,sizeof(a))
      6 using namespace std;
      7 const int N=2506;
      8 struct son
      9 {
     10     int v,next;
     11 };
     12 son a1[N];
     13 int first[N],e;
     14 void addbian(int u,int v)
     15 {
     16     a1[e].v=v;
     17     a1[e].next=first[u];
     18     first[u]=e++;
     19 }
     20 
     21 int m,u,o,n,ans,cnt;
     22 ll sum;
     23 int fa[N],dfn[N],low[N],hh,cutsum;
     24 int cut[N],num[N*3],color[N];
     25 bool vis[N],flag[N];
     26 
     27 void tarjen(int fa,int x)
     28 {
     29     int child=0;
     30     low[x]=dfn[x]=++cnt;
     31     for(int i=first[x];i!=-1;i=a1[i].next)
     32     {
     33         int temp=a1[i].v;
     34         if(dfn[temp]==-1)
     35         {
     36             ++child;
     37             tarjen(x,temp);
     38             if(low[x]>low[temp])low[x]=low[temp];
     39             if(low[temp]>=dfn[x])
     40               cut[x]=1;
     41         }
     42         else
     43           if(dfn[temp]<dfn[x]&&temp!=fa)
     44             if(low[x]>dfn[temp])
     45               low[x]=dfn[temp];
     46     }
     47     if(fa<0&&child==1)
     48       cut[x]=0;
     49 }
     50 
     51 void out11()
     52 {
     53     printf("
    ");
     54     for(int i=1;i<=n;++i)
     55       printf("%d
    ",cut[i]);
     56     printf("
    ");
     57     for(int i=1;i<=n;++i)
     58       printf("%d
    ",color[i]);
     59     printf("
    ");
     60 }
     61 
     62 void chu()
     63 {
     64     mem(first,-1);mem(a1,0);e=0;
     65     mem(dfn,-1);mem(low,0);cnt=0;
     66     mem(cut,0);mem(num,0);mem(color,-1);
     67     mem(flag,0);
     68     ans=0;sum=1;cnt=0;hh=0;
     69     cutsum=0;
     70     n=0;
     71 }
     72 
     73 int now;
     74 
     75 void dfs(int x)
     76 {
     77     vis[x]=1;
     78     //printf("x=%d
    ",x);
     79     if(color[x]!=-1)
     80       color[x]=-2;
     81     else
     82       color[x]=now;
     83     for(int i=first[x];i!=-1;i=a1[i].next)
     84     {
     85         int temp=a1[i].v;
     86         if(cut[temp]||vis[temp])continue;
     87         dfs(temp);
     88     }
     89 }
     90 
     91 int main(){
     92     
     93     //freopen("1.txt","r",stdin);
     94     //freopen("bzoj_2730.in","r",stdin);
     95     //freopen("bzoj_2730.out","w",stdout);
     96     
     97     scanf("%d",&m);
     98     for(int l=1;m!=0;++l)
     99     {
    100         chu();
    101         
    102         for(int i=1;i<=m;++i)
    103         {
    104             scanf("%d%d",&u,&o);
    105             addbian(u,o);
    106             addbian(o,u);
    107             n=n>u?n:u;
    108             n=n>o?n:o;
    109         }
    110         
    111         for(int i=1;i<=n;++i)
    112           if(dfn[i]==-1)
    113                 tarjen(-1,i);
    114         
    115         
    116         for(int i=1;i<=n;++i)
    117             if(cut[i])
    118             {
    119                 mem(vis,0);
    120                 for(int j=first[i];j!=-1;j=a1[j].next)
    121                 {
    122                     int temp=a1[j].v;
    123                     if(cut[temp]||vis[temp])continue;
    124                     now=++hh;
    125                     //printf("temp=%d
    ",temp);
    126                     dfs(temp);
    127                 }
    128             }
    129         
    130         for(int i=1;i<=n;++i)
    131         {
    132             if(cut[i])++cutsum;
    133             if(vis[i]==-1||cut[i])continue;
    134             ++num[color[i]];
    135         }
    136         
    137         for(int i=1;i<=hh;++i)
    138           if(num[i])
    139           {
    140                 ++ans;
    141                 sum*=num[i];
    142             }
    143         
    144         //out11();
    145         
    146         if(cutsum==0)//点双连通分量
    147         {
    148             ans=2;
    149             sum=(n-1)*n/2;
    150         }
    151         
    152         //printf("cutsum=%d
    ",cutsum);
    153         
    154         printf("Case %d: %d %lld
    ",l,ans,sum);
    155         scanf("%d",&m);
    156     }
    157     //while(1);
    158     return 0;
    159 }#include<cstdio>
    160 #include<cstring>
    161 #include<iostream>
    162 #define ll long long
    163 #define mem(a,b) memset(a,b,sizeof(a))
    164 using namespace std;
    165 const int N=2506;
    166 struct son
    167 {
    168     int v,next;
    169 };
    170 son a1[N];
    171 int first[N],e;
    172 void addbian(int u,int v)
    173 {
    174     a1[e].v=v;
    175     a1[e].next=first[u];
    176     first[u]=e++;
    177 }
    178 
    179 int m,u,o,n,ans,cnt;
    180 ll sum;
    181 int fa[N],dfn[N],low[N],hh,cutsum;
    182 int cut[N],num[N*3],color[N];
    183 bool vis[N],flag[N];
    184 
    185 void tarjen(int fa,int x)
    186 {
    187     int child=0;
    188     low[x]=dfn[x]=++cnt;
    189     for(int i=first[x];i!=-1;i=a1[i].next)
    190     {
    191         int temp=a1[i].v;
    192         if(dfn[temp]==-1)
    193         {
    194             ++child;
    195             tarjen(x,temp);
    196             if(low[x]>low[temp])low[x]=low[temp];
    197             if(low[temp]>=dfn[x])
    198               cut[x]=1;
    199         }
    200         else
    201           if(dfn[temp]<dfn[x]&&temp!=fa)
    202             if(low[x]>dfn[temp])
    203               low[x]=dfn[temp];
    204     }
    205     if(fa<0&&child==1)
    206       cut[x]=0;
    207 }
    208 
    209 void out11()
    210 {
    211     printf("
    ");
    212     for(int i=1;i<=n;++i)
    213       printf("%d
    ",cut[i]);
    214     printf("
    ");
    215     for(int i=1;i<=n;++i)
    216       printf("%d
    ",color[i]);
    217     printf("
    ");
    218 }
    219 
    220 void chu()
    221 {
    222     mem(first,-1);mem(a1,0);e=0;
    223     mem(dfn,-1);mem(low,0);cnt=0;
    224     mem(cut,0);mem(num,0);mem(color,-1);
    225     mem(flag,0);
    226     ans=0;sum=1;cnt=0;hh=0;
    227     cutsum=0;
    228     n=0;
    229 }
    230 
    231 int now;
    232 
    233 void dfs(int x)
    234 {
    235     vis[x]=1;
    236     //printf("x=%d
    ",x);
    237     if(color[x]!=-1)
    238       color[x]=-2;
    239     else
    240       color[x]=now;
    241     for(int i=first[x];i!=-1;i=a1[i].next)
    242     {
    243         int temp=a1[i].v;
    244         if(cut[temp]||vis[temp])continue;
    245         dfs(temp);
    246     }
    247 }
    248 
    249 int main(){
    250     
    251     //freopen("1.txt","r",stdin);
    252     //freopen("bzoj_2730.in","r",stdin);
    253     //freopen("bzoj_2730.out","w",stdout);
    254     
    255     scanf("%d",&m);
    256     for(int l=1;m!=0;++l)
    257     {
    258         chu();
    259         
    260         for(int i=1;i<=m;++i)
    261         {
    262             scanf("%d%d",&u,&o);
    263             addbian(u,o);
    264             addbian(o,u);
    265             n=n>u?n:u;
    266             n=n>o?n:o;
    267         }
    268         
    269         for(int i=1;i<=n;++i)
    270           if(dfn[i]==-1)
    271                 tarjen(-1,i);
    272         
    273         
    274         for(int i=1;i<=n;++i)
    275             if(cut[i])
    276             {
    277                 mem(vis,0);
    278                 for(int j=first[i];j!=-1;j=a1[j].next)
    279                 {
    280                     int temp=a1[j].v;
    281                     if(cut[temp]||vis[temp])continue;
    282                     now=++hh;
    283                     //printf("temp=%d
    ",temp);
    284                     dfs(temp);
    285                 }
    286             }
    287         
    288         for(int i=1;i<=n;++i)
    289         {
    290             if(cut[i])++cutsum;
    291             if(vis[i]==-1||cut[i])continue;
    292             ++num[color[i]];
    293         }
    294         
    295         for(int i=1;i<=hh;++i)
    296           if(num[i])
    297           {
    298                 ++ans;
    299                 sum*=num[i];
    300             }
    301         
    302         //out11();
    303         
    304         if(cutsum==0)//点双连通分量
    305         {
    306             ans=2;
    307             sum=(n-1)*n/2;
    308         }
    309         
    310         //printf("cutsum=%d
    ",cutsum);
    311         
    312         printf("Case %d: %d %lld
    ",l,ans,sum);
    313         scanf("%d",&m);
    314     }
    315     //while(1);
    316     return 0;
    317 }
    code
  • 相关阅读:
    get和post的区别
    关于webWorker的理解和简单例子
    JavaScript停止事件冒泡和取消事件默认行为
    深入理解js构造函数
    js之yeild
    文件组织方式
    HTML5新增的标签和属性归纳
    css3新增属性
    CSS3 transition介绍
    Mysql安装
  • 原文地址:https://www.cnblogs.com/A-LEAF/p/7347165.html
Copyright © 2020-2023  润新知