• bzoj 2730: [HNOI2012]矿场搭建


      1 #include<cstdio>
      2 #include<cstring>
      3 #include<iostream>
      4 #define M 508
      5 using namespace std;
      6 int T=1,m,n,head[M],K,next[10*M],u[10*M],cnt,f[M],c[M],fa[M],dfn[M],low[M],time1,ans,bi[M],sum[M];
      7 long long ans1=1;
      8 void jia(int a1,int a2)
      9 {
     10     cnt++;
     11     next[cnt]=head[a1];
     12     head[a1]=cnt;
     13     u[cnt]=a2;
     14 }
     15 void tarjin(int a1,int deep)
     16 {
     17     time1++;
     18     dfn[a1]=low[a1]=time1;
     19     c[a1]=-1;
     20     int tot=0;
     21     for(int i=head[a1];i;i=next[i])
     22     if(u[i]!=fa[a1])
     23       {
     24         fa[u[i]]=a1;
     25         if(!c[u[i]])
     26           {
     27             tarjin(u[i],deep+1);
     28             low[a1]=min(low[a1],low[u[i]]);
     29             tot++;
     30             if(deep==1&&tot>1)
     31               f[a1]=1;
     32             if(deep>1&&low[u[i]]>=dfn[a1])
     33               f[a1]=1;
     34           }
     35         else  if(c[u[i]]==-1&&u[i]!=fa[a1])
     36                  low[a1]=min(low[a1],dfn[u[i]]);
     37       }
     38     c[a1]=1;
     39 }
     40 void dfs(int a1)
     41 {
     42     c[a1]=1;
     43     if(!bi[a1])
     44       bi[a1]=time1;
     45     else
     46       bi[a1]=-1;
     47     for(int i=head[a1];i;i=next[i])
     48       if(!c[u[i]]&&!f[u[i]])
     49         dfs(u[i]);
     50     return;
     51 }
     52 int main()
     53 {
     54     for(;scanf("%d",&m),m;T++){
     55     ans=cnt=n=0;
     56     ans1=1;
     57     memset(head,0,sizeof(head));
     58     memset(bi,0,sizeof(bi));
     59     memset(f,0,sizeof(f));
     60     memset(sum,0,sizeof(sum));
     61     for(int i=1;i<=m;i++)
     62       {
     63         int a1,a2;
     64         scanf("%d%d",&a1,&a2);
     65         n=max(n,a1);
     66         n=max(n,a2);
     67         jia(a1,a2);
     68         jia(a2,a1);
     69       }
     70     time1=0;
     71     for(int i=1;i<=n;i++)
     72       {
     73          f[i]=0;
     74          c[i]=0;
     75          fa[i]=0;
     76       }
     77     tarjin(1,1);
     78     time1=0;
     79     for(int i=1;i<=n;i++)
     80       if(f[i])
     81         {
     82           memset(c,0,sizeof(c));
     83           for(int j=head[i];j;j=next[j])
     84             if(!c[u[j]]&&!f[u[j]])
     85               {
     86                 time1++;
     87                 dfs(u[j]);
     88               }
     89         }
     90     for(int i=1;i<=n;i++)
     91       if(bi[i]!=-1)
     92         sum[bi[i]]++;
     93     for(int i=1;i<=time1;i++)
     94       if(sum[i])
     95         {
     96             ans++;
     97             ans1*=sum[i];
     98         }
     99     printf("Case %d: ",T);
    100     if(ans)
    101       printf("%d %lld
    ",ans,ans1);
    102     else
    103       printf("2 %d
    ",n*(n-1)/2);}
    104     return 0;
    105 }

    先用tarjin找割点 割点条件u1是树根,且有大于1棵子树,u1不是树根,low[u[i]]>dfn[u1],把和一个割点相连的联通块建出口。

  • 相关阅读:
    Swift 3 中的访问控制 open public internal fileprivate private
    swift3.0 创建一个app引导页面
    cocoapods安装及常用命令
    swift 多线程及GCD
    swift 键盘属性与事件
    [bzoj2588] Count on a tree
    [JSOI2007] 文本生成器
    18.09.22模拟赛T2 历史
    [USACO18OPEN] Talent Show
    [国家集训队] 整数的lqp拆分
  • 原文地址:https://www.cnblogs.com/xydddd/p/5304569.html
Copyright © 2020-2023  润新知