P3225 [HNOI2012]矿场搭建

题目描述
煤矿工地可以看成是由隧道连接挖煤点组成的无向图。为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处。于是矿主决定在某些挖煤点设立救援出口,使得无论哪一个挖煤点坍塌之后,其他挖煤点的工人都有一条道路通向救援出口。
请写一个程序,用来计算至少需要设置几个救援出口,以及不同最少救援出口的设置方案总数。
输入输出格式
输入格式:
输入文件有若干组数据,每组数据的第一行是一个正整数 N(N<=500),表示工地的隧道数,接下来的 N 行每行是用空格隔开的两个整数 S 和 T,表示挖 S 与挖煤点 T 由隧道直接连接。输入数据以 0 结尾。
输出格式:
输入文件中有多少组数据,输出文件 output.txt 中就有多少行。每行对应一组输入数据的 结果。其中第 i 行以 Case i: 开始(注意大小写,Case 与 i 之间有空格,i 与:之间无空格,: 之后有空格),其后是用空格隔开的两个正整数,第一个正整数表示对于第 i 组输入数据至少需 要设置几个救援出口,第二个正整数表示对于第 i 组输入数据不同最少救援出口的设置方案总 数。输入数据保证答案小于 2^64。输出格式参照以下输入输出样例。

首先这个题首先我们讨论两种情况,第一种情况就是这个图本来就是一个点连通图,也就是说不存在割点。那么我们任意去掉一个点以后,这个图仍然是联通的。那么我们的逃生出口一定要有两个,保证如果一个逃生出口Over了,还有另外一个逃生出口可以保命。所以总方案数就是Cn2 。
然后第二种情况,这个图存在割点。那么如果坍塌的是这个割点,这个图就会变得不连通。对于那种只和一个割点相连的块,我们至少要在这个块里面选出来一个建逃生通道,而且也是任意选择。假设这个块有p个节点,那么该块的方案数就是Cp-11。(有一个割点所以-1)(p为该块的点数)
针对第二种情况总结来看对于每一个双联通分量我们一共有三种情况:
1.如果这个双联通分量里面没有割点。那么在这个双联通分量里面需要建Cp2个出口。
2.如果双联通分量只有一个割点,那么再非割点的地方任意选择一个点来建逃生出口都没有问题。方案数为Cp-11。
3.若该双联通分量里面有两个割点,那么我们就不需要建立了,因为无论哪一个节点hehe了,其他的点都可以通过其他的没有hehe的点跑到别的双联通分量里面去。
然后以上是针对一个双联通分量的,那么至于总共的方案,我们就可以利用一下组合数学了.....(qwq)。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define INF 0x7fffffff
#define MAXN 100010
#define ll long long
using namespace std;
int n,m;
struct point{
    int from;
    int to;
    int next;
}edge[MAXN*2];
int total,head[MAXN];
void add(int f,int t){
    total++;
    edge[total].from=f;
    edge[total].to=t;
    edge[total].next=head[f];
    head[f]=total;
}
int Yeasion[MAXN],Nein[MAXN];
int stack[MAXN],top,ken;
vector<int>block[MAXN];
int cut[MAXN],cnt,root;
void Tarjan(int now,int fa){
    Yeasion[now]=Nein[now]=++ken;
    stack[++top]=now; int child=0;
    for(int i=head[now];i;i=edge[i].next){
        if(!Yeasion[edge[i].to]){
            Tarjan(edge[i].to,now); child++;
            Nein[now]=min(Nein[now],Nein[edge[i].to]);
            if(now==root&&child>1) cut[now]=1;
            if(now!=root&&Yeasion[now]<=Nein[edge[i].to]) cut[now]=1;
            if(Yeasion[now]<=Nein[edge[i].to]){
                cnt++; block[cnt].clear();
                int pass;
                do{
                    pass=stack[top--];
                    block[cnt].push_back(pass);
                }while(pass!=edge[i].to);/////
                block[cnt].push_back(now);
            }
        }
        else Nein[now]=min(Nein[now],Yeasion[edge[i].to]);
    }
}
void Solve(){
    n=0;
    for(int i=1;i<=m*2;i++){
        Yeasion[i]=Nein[i]=0;
        head[i]=0;
        cut[i]=0;
    }top=ken=cnt=0;
    for(int i=1;i<=m;i++){
        int x; int y;
        scanf("%d%d",&x,&y);
        n=max(n,max(x,y));
        add(x,y); add(y,x);
    };
    for(int i=1;i<=n;i++){
        if(!Yeasion[i]){
            root=i;
            Tarjan(i,-1);
        }
    }
    ll res=0,num=1;
    for(int i=1;i<=cnt;i++){
        int yor=0;
        int len=block[i].size();
        for(int j=0;j<len;j++)
            if(cut[block[i][j]]) yor++;
        if(yor==0) res+=2,num=num*(len-1)*len/2;
        else if(yor==1) res++,num=num*(len-1);
    }
    printf("%lld %lld\n",res,num);
}
int main(){
    int t=1;
    while(scanf("%d",&m)&&m){
        printf("Case %d: ",t++);
        Solve();
    } return 0;
}

[luoguP3325][HNOI2012]矿场搭建的更多相关文章

  1. bzoj2730 [HNOI2012]矿场搭建 (UVAlive5135 Mining Your Own Business)

    2730: [HNOI2012]矿场搭建 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1147  Solved: 528[Submit][Statu ...

  2. BZOJ 2730: [HNOI2012]矿场搭建( tarjan )

    先tarjan求出割点.. 割点把图分成了几个双连通分量..只需dfs找出即可. 然后一个bcc有>2个割点, 那么这个bcc就不用建了, 因为一定可以走到其他救援出口. 只有一个割点的bcc就 ...

  3. 洛谷 P3225 [HNOI2012]矿场搭建 解题报告

    P3225 [HNOI2012]矿场搭建 题目描述 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖煤 ...

  4. 【BZOJ】2730: [HNOI2012]矿场搭建【Tarjan找割点】【分联通块割点个数】

    2730: [HNOI2012]矿场搭建 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3230  Solved: 1540[Submit][Stat ...

  5. Tarjan 点双+割点+DFS【洛谷P3225】 [HNOI2012]矿场搭建

    P3225 [HNOI2012]矿场搭建 题目描述 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖煤 ...

  6. [BZOJ2730][HNOI2012]矿场搭建 点双 割点

    2730: [HNOI2012]矿场搭建 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2852  Solved: 1344[Submit][Stat ...

  7. 【BZOJ2730】[HNOI2012]矿场搭建 Tarjan

    [BZOJ2730][HNOI2012]矿场搭建 Description 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处. ...

  8. BZOJ 2730:[HNOI2012]矿场搭建(割点+连通块)

    [HNOI2012]矿场搭建 Description 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖 ...

  9. BZOJ_2730_ [HNOI2012]矿场搭建_点双联通分量

    BZOJ_2730_ [HNOI2012]矿场搭建_点双联通分量 Description 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路 ...

随机推荐

  1. cloudermanger安装时需要安装或彻底正确卸载再安装orcal-java7-installer、oracle-java7-set-default(ubuntu14.04版本)(图文详解)

    不多说,直接上干货! 安装orcal-java7-installer和oracle-java7-set-default 安装JDK1.7 (所有节点)CDH要求至少是Oracle JDK7,Ubunt ...

  2. 016-hibernateutils模板

    package ${enclosing_package}; import org.hibernate.HibernateException; import org.hibernate.Session; ...

  3. java中的输入输出方法

    输入 import java.util.Scanner; public class EnterTest { public static void main(String[] args) { //主方法 ...

  4. 游戏AI的生命力源自哪里?为你揭开MOBA AI的秘密!

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由wataloo发表在专栏wataloo的试验田 1 设计概要 1.1 设计原则和目的 英雄AI的目的主要有: 1.新手过渡局,让玩家刚 ...

  5. 二、hadoop文件操作

    1.使用hadoop命令查看hdfs下文件 [root@localhost hadoop-2.7.2]# hadoop fs -ls hdfs://192.168.211.129:9000/  (最后 ...

  6. tomcat-dbcp数据库连接池配置以及使用时候的一些坑

    一.数据库连接池 开发的时候经常会需要对数据库进行一些操作,比如说常见的增删改查之类的,当数据量小的时候,可以直接进行操作,但是当数据量增多的时候,每一次连接以及释放数据库都会耗费一定的时间,这个时候 ...

  7. Python实现抓取CSDN博客首页文章列表

    1.使用工具: Python3.5 BeautifulSoup 2.抓取网站: csdn首页文章列表 http://blog.csdn.net/ 3.分析网站文章列表代码: 4.实现抓取代码: __a ...

  8. 使用 Azure CLI 创建虚拟机

    使用 az vm create 命令创建虚拟机. 创建虚拟机时,可使用多个选项,例如操作系统映像.磁盘大小调整和管理凭据. 在此示例中,创建了一个名为“myVM”的运行 Ubuntu Server 的 ...

  9. node.js发邮件

    在node上使用第三方类库(nodemailer)发邮件是一件很esay的事情:) app.js   以QQ邮箱为例 var nodemailer = require('nodemailer'); v ...

  10. JSON初试

    本次在课堂上老师教我使用JSON. 本次的教学网站是:https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/JSON?td ...