zoukankan      html  css  js  c++  java
  • 矿工安全生产

    矿工安全生产

    题目链接:https://pta.patest.cn/pta/test/4943/exam/4/question/75471

    题目大意:给出$n$条边和若干个点,现要求选择部分点放置逃生装置,使得不管哪个点倒塌,不在此点的所有人都能到达逃生装置逃生。问最少放多少逃生装置,共有几种放置方法.

    参考博客:http://blog.csdn.net/jinglinxiao/article/details/64657078

    tarjan

    当且仅当图中割点被破坏,图的连通性发生改变。故去除割点后连通块的个数即为逃生装置的数量。

    任取一点为根,建立一颗DFS树,则树中结点有三种情况:

    • 根结点。根结点有大于$1$颗子树$Leftrightarrow$根为割点;
    • 叶节点。叶节点不为割点;
    • 非根非叶结点。$dfn[i]>low[i] Leftrightarrow i$为割点,其中$dfs[i]$为结点$i$在DFS遍历中的顺序,$low[i]$为$i$及$i$联通的子树中最小的$dfn[j]$.

    代码如下:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <string>
     4 #include <cstring>
     5 #include <algorithm>
     6 #include <stack>
     7 #include <vector>
     8 using namespace std;
     9 typedef long long ll;
    10 vector<int>e[50005];
    11 int t,n,root,dfn[50005],low[50005],tot;
    12 bool vis[50005],ge[50005];
    13 void init(){
    14     for(int i=0;i<=50000;++i)e[i].clear();
    15     memset(vis,0,sizeof(vis));
    16     memset(ge,0,sizeof(ge));
    17     tot=0;n=0;root=1;
    18     while(t--){
    19         int u,v;
    20         scanf("%d%d",&u,&v);
    21         e[u].push_back(v);
    22         e[v].push_back(u);
    23         n=max(v,n);
    24         n=max(u,n);
    25     }
    26 }
    27 void tar(int u,int p){
    28     low[u]=dfn[u]=tot++;
    29     vis[u]=1;
    30     int cnt=0;
    31     for(int i=0;i<(int)e[u].size();++i){
    32         int v=e[u][i];
    33         if(v==p)continue;
    34         if(!vis[v]){
    35             tar(v,u);
    36             cnt++;
    37             low[u]=min(low[u],low[v]);
    38         }else low[u]=min(low[u],dfn[v]);
    39     }
    40     if((u==root&&cnt>1)||(u!=root&&cnt&&low[u]>=dfn[u]))ge[u]=1;
    41 }
    42 ll dfs(int u){
    43     int cnt=1;
    44     vis[u]=1;
    45     for(int i=0;i<(int)e[u].size();++i){
    46         int v=e[u][i];
    47         if(!vis[v]&&!ge[v])cnt+=dfs(v);
    48     }
    49     return cnt;
    50 }
    51 int main(void){
    52     while(scanf("%d",&t)){
    53         if(!t)break;
    54         init();
    55         tar(root,-1);
    56         memset(vis,0,sizeof(vis));
    57         ll a1=0,a2=1;
    58         for(int i=1;i<=n;++i)
    59         if(!vis[i]&&!ge[i]){
    60             a1++;
    61             a2*=dfs(i);
    62         }
    63         printf("%lld %lld
    ",a1,a2);
    64     }
    65 }
  • 相关阅读:
    vue-cli项目打包出现空白页和路径错误问题
    Git操作手册
    Atom Editor 插件 atom-less 的使用方法
    Vue搭建
    使绝对定位高宽自适应
    原生JS表单序列化
    前端代码有关搜索引擎的代码
    网页局部打印
    万维网
    浅淡传统企业进入移动互联网的几种方式
  • 原文地址:https://www.cnblogs.com/barrier/p/6601398.html
Copyright © 2011-2022 走看看