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

    矿场搭建

    题目链接

    根据题意,发生事故时会有一个挖煤点坍塌,

    只有当这个点是割点,会对图的连通性产生影响,

    我们首先Tarjan一遍找到所有割点,将原图除去这些割点后,

    遍历一遍,找出所有连通块,分三种情况讨论:

    1、该连通块连接着两个及以上的割点,这时如果有一个割点被摧毁,

    还可以从另一个割点到达其他连通块,不需要建逃生通道

    2、该连通块连接着一个割点,若这个割点被摧毁,该连通块的人就无法逃生,

    必须建一个出口(从该连通块的所有节点中选一个,ans*=size)

    3、该连通块没有割点相连,要建两个出口,如果其中一个被摧毁,还可以从另一个逃出去

    ans*=C(size,2);

     1 #include<algorithm>
     2 #include<cstdio>
     3 #define reset(a) std::fill(a,a+1+n,0)
     4 #define min(a,b) ((a)<(b)?(a):(b))
     5 #define max(a,b) ((a)>(b)?(a):(b))
     6 #define N 50020
     7 int n,m,dfn[N],low[N],vis[N],tot,k,T;
     8 const int ch_top=4e7+3;
     9 char ch[ch_top],*now_r=ch-1,*now_w=ch-1;
    10 inline int read(){
    11     while(*++now_r<'0');
    12     register int x=*now_r-'0';
    13     while(*++now_r>='0')x=x*10+*now_r-'0';
    14     return x;
    15 }
    16 long long ans;
    17 bool gd[N];
    18 int Head[N],to[N<<1],next[N<<1],num;
    19 void Tarjan(int u){
    20     dfn[u]=low[u]=++tot;
    21     int cnt=0;
    22     for(int i=Head[u];i;i=next[i]){
    23         int v=to[i];
    24         if(!dfn[v]){
    25             Tarjan(v); cnt++;
    26             low[u]=min(low[u],low[v]);
    27             if((u==1&&cnt>1)||(u!=1&&low[v]>=dfn[u]))
    28              gd[u]=1;
    29         }
    30         else low[u]=min(low[u],dfn[v]);
    31     }
    32 }
    33 int dfs(int t){
    34     int sz=1; vis[t]=1;
    35     for(int i=Head[t];i;i=next[i])
    36      if(!vis[to[i]]&&!gd[to[i]])
    37          sz+=dfs(to[i]);
    38      else if(vis[to[i]]!=T&&gd[to[i]]){
    39          k++; vis[to[i]]=T;
    40      }
    41     return sz;
    42 }
    43 int main()
    44 {
    45     fread(ch,1,ch_top,stdin);
    46     int now=0;
    47     m=read();
    48     while(m){
    49         if(!m) break;
    50         reset(Head); reset(gd);
    51         reset(vis); reset(dfn);
    52         num=tot=n=T=0;
    53         int x,y;
    54         for(int i=1;i<=m;i++){
    55             x=read(); y=read();
    56             to[++num]=y;
    57             next[num]=Head[x];
    58             Head[x]=num;
    59             to[++num]=x;
    60             next[num]=Head[y];
    61             Head[y]=num;
    62             n=max(n,max(x,y));
    63         }
    64         int cnt=0;
    65         Tarjan(1);ans=1;
    66         for(int i=1;i<=n;i++)
    67          if(!gd[i]&&!vis[i]){
    68              k=0; T++;
    69              int size=dfs(i);
    70              if(k==0) ans*=(long long)size*(size-1)/2,cnt+=2;
    71              else if(k==1) ans*=size,cnt++;
    72          }
    73         printf("Case %d: %d %lld
    ",++now,cnt,ans);
    74         m=read();
    75     }
    76     return 0;
    77 }

    双倍经验:UVA1108

  • 相关阅读:
    进程之管道Pipe,数据共享Manager,进程池Poo
    进程之锁,信息量,事件,队列,生产者消费者模型,joinablequeue
    网络编程之sock server,自定义一个与sock server类相似的功能,支持多客户端通信
    网络编程之粘包解决方案
    进程之进程创建的两种方式,两种传值的方式,验证进程间数据隔离,join,守护进程,僵尸进程,孤儿进程
    毕业设计开题报告任务书参考文献格式和数量要求
    剑指offer-替换空格
    剑指offer-二维数组中的查找
    用forward和sendRedirect转发时的区别
    ServletContext实现显示用户在线人数
  • 原文地址:https://www.cnblogs.com/yjkhhh/p/9413925.html
Copyright © 2011-2022 走看看