zoukankan      html  css  js  c++  java
  • BZOJ2730: [HNOI2012]矿场搭建

    n<=500条边的图,求:最少设置多少关键点,使得当任意某一个点不能经过时其他点都至少能到达一个关键点,并输出方案数。

    tarjan求点双,如果一个点双里面没有割点,那这就是一个孤立的点双分量,至少要设置两个点。如果有割点,大概是这样的情况:

    红色的这些“叶子”分量,也就是只有一个割点的分量,是一定要设置一个关键点的,因为如果唯一的割点走不了了,这个分量的点就只能在分量里面活动了,而这样也可以使其他有多个割点的分量可以在一个割点被破坏时到达其他的关键点。方案数就乘上这些分量的大小-1即可。

    在一个块里选两个点的方案记得除以2。。。。。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<stdlib.h>
     4 #include<algorithm>
     5 //#include<assert.h>
     6 #include<math.h>
     7 //#include<iostream>
     8 using namespace std;
     9 
    10 int n,m;
    11 #define maxn 1011
    12 #define maxm 2011
    13 int id[maxn],cntid;
    14 struct Edge{int to,next;}edge[maxm];int first[maxn],le;
    15 int getid(int x) {if (id[x]) return id[x];return (id[x]=++cntid);}
    16 void in(int x,int y) {Edge &e=edge[le];e.to=y;e.next=first[x];first[x]=le++;}
    17 void insert(int x,int y) {in(x,y);in(y,x);}
    18 int low[maxn],dfn[maxn],Time,tot,bel[maxn],size[maxn],cut[maxn],sta[maxm],top;bool iscut[maxn];
    19 void tarjan(int x,int fa)
    20 {
    21     low[x]=dfn[x]=++Time;
    22     int son=0;
    23     for (int i=first[x];i;i=edge[i].next)
    24     {
    25         Edge &e=edge[i];
    26         if (!dfn[e.to])
    27         {
    28             sta[++top]=i;
    29             son++;
    30             tarjan(e.to,x);
    31             low[x]=min(low[x],low[e.to]);
    32             if (low[e.to]>=dfn[x])
    33             {
    34                 iscut[x]=1;tot++;size[tot]=cut[tot]=0;
    35                 for (;;)
    36                 {
    37                     int u=edge[sta[top]].to,v=edge[sta[top]^1].to;
    38                     if (bel[u]!=tot) bel[u]=tot,size[tot]++,cut[tot]+=iscut[u];
    39                     if (bel[v]!=tot) bel[v]=tot,size[tot]++,cut[tot]+=iscut[v];
    40                     top--;
    41                     if (v==x && u==e.to) break;
    42                 }
    43             }
    44         }
    45         else if (e.to!=fa && dfn[e.to]<dfn[x])
    46         {
    47             sta[++top]=i;
    48             low[x]=min(low[x],dfn[e.to]);
    49         }
    50     }
    51     if (!fa && son<=1) iscut[x]=0,cut[bel[x]]--;
    52 }
    53 void tarjan()
    54 {
    55     memset(dfn,0,sizeof(dfn));
    56     memset(bel,0,sizeof(bel));
    57     memset(iscut,0,sizeof(iscut));
    58     Time=tot=top=0;
    59     for (int i=1;i<=n;i++)
    60         if (!dfn[i]) tarjan(i,0);
    61 }
    62 #define LL long long
    63 int main()
    64 {
    65     int x,y,Case=0;
    66     while (scanf("%d",&n) && n)
    67     {
    68         cntid=0;le=2;
    69         memset(first,0,sizeof(first));
    70         memset(id,0,sizeof(id));
    71         for (int i=1;i<=n;i++)
    72         {
    73             scanf("%d%d",&x,&y);
    74             x=getid(x),y=getid(y);
    75             insert(x,y);
    76         }
    77         m=n;n=cntid;
    78         tarjan();
    79         LL ans=1,sum=0;
    80         for (int i=1;i<=tot;i++)
    81         {
    82             if (!cut[i]) sum+=2,ans=ans*size[i]*(size[i]-1)/2;
    83             else if (cut[i]==1) sum++,ans=ans*(size[i]-1);
    84         }
    85         printf("Case %d: %lld %lld
    ",++Case,sum,ans);
    86     }
    87     return 0;
    88 }
    View Code
  • 相关阅读:
    >>> fout = open('output.txt', 'w') Traceback (most recent call last): File "<stdin>", line 1, in <module> PermissionError: [Errno 13] Permission denied: 'output.txt'
    Python元组术语
    Python元组与列表_元组与字典
    Python元组_参数长度可变
    Python元组_赋值与返回值
    Python元组_不可修改
    第二篇-bmob云端服务器的发现
    第一篇-关于语言与计划
    《JavaScript》JS中的常用方法attr(),splice()
    Java接口interface,匿名内部类
  • 原文地址:https://www.cnblogs.com/Blue233333/p/7665501.html
Copyright © 2011-2022 走看看