http://www.lydsy.com/JudgeOnline/problem.php?id=2730 (题目链接)

题意

  给出一张图,问如果删掉其中一个点,使得其他每个节点都有一个安全撤离的出口,最少需要设立多少个出口,有多少种方案。

Solution

  很明显,一张图至少要设立2个出口(一个点双连通分量),如果删掉不是割点的点,对答案不会有什么限制,考虑删掉的点是割点。

  我们对割点以外的联通快进行染色,每一种颜色就表示在这些同样的颜色中的节点至少要设置一个出口,若一个节点被染成了多种颜色,那么表明在此处设立出口不是最优的。

细节

  十个Tarjan五个错。。注意判断割点的条件,当判断搜索树根是不是割点时,有点小麻烦。另外,染色的时候不走割点。

代码

// bzoj2730
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define LL long long
#define inf 2147483640
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std; const int maxn=1010;
struct edge {int to,next;}e[maxn<<1];
int low[maxn],dfn[maxn],head[maxn],cut[maxn],vis[maxn],id[maxn],sum[maxn];
int cnt,ind,m,n; void Init() {
cnt=ind=n=0;
memset(head,0,sizeof(head));
memset(vis,0,sizeof(vis));
memset(cut,0,sizeof(cut));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(sum,0,sizeof(sum));
memset(id,0,sizeof(id));
}
void link(int u,int v) {
e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;
e[++cnt].to=u;e[cnt].next=head[v];head[v]=cnt;
}
void Tarjan(int x,int fa,int rt) {
int tot=0;
dfn[x]=low[x]=++ind;
for (int i=head[x];i;i=e[i].next) if (e[i].to!=fa) {
if (!dfn[e[i].to]) {
Tarjan(e[i].to,x,rt);
low[x]=min(low[x],low[e[i].to]);
if (low[e[i].to]>=dfn[x] && x!=rt) cut[x]=1; //important
else if (x==rt) tot++;
}
else low[x]=min(low[x],dfn[e[i].to]);
}
if (tot>1) cut[x]=1; //important
}
void dfs(int x,int col) {
vis[x]=cnt;
if (!id[x]) id[x]=col;
else id[x]=-1;
for (int i=head[x];i;i=e[i].next)
if (vis[e[i].to]!=cnt && !cut[e[i].to]) dfs(e[i].to,col);
}
int main() {
int T=0;
while (1) {
scanf("%d",&m);
if (m==0) break;
printf("Case %d: ",++T);
Init();
for (int u,v,i=1;i<=m;i++) {
scanf("%d%d",&u,&v);
link(u,v);n=max(n,max(u,v));
}
for (int i=1;i<=n;i++) if (!dfn[i]) Tarjan(i,0,i);
cnt=0;int col=0;
for (int i=1;i<=n;i++) if (cut[i]) {
cnt++;
for (int j=head[i];j;j=e[j].next)
if (vis[e[j].to]!=cnt && !cut[e[j].to]) dfs(e[j].to,++col);
}
for (int i=1;i<=n;i++) if (id[i]!=-1) sum[id[i]]++;
int tot=0;LL ans=1;
for (int i=1;i<=col;i++) if (sum[i]) tot++,ans=ans*sum[i];
if (!tot) printf("2 %d\n",n*(n-1)/2);
else printf("%d %lld\n",tot,ans);
}
return 0;
}

  

【bzoj2730】 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. [BZOJ2730][HNOI2012]矿场搭建 点双 割点

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

  3. BZOJ2730——[HNOI2012]矿场搭建

    bzoj2730 & world final 2011 H 1.题目大意:就是有一个无向图,让你在里面选择点,使得,无论哪个点没了以后,其他的点都能到达你选择的任何一个点,输出最少 选择几个点 ...

  4. BZOJ2730 [HNOI2012]矿场搭建 - Tarjan割点

    Solution 输入中没有出现过的矿场点是不用考虑的, 所以不用考虑只有 一个点 的点双联通分量. 要使某个挖矿点倒塌, 相当于割去这个点, 所以我们求一遍割点和点双联通分量. 之后的点双联通分量构 ...

  5. BZOJ2730: [HNOI2012]矿场搭建

    传送门 图的连通性相关的必和割点割边之类的有关. 题目要求对于一个无向图,任意一点被删除后,所有点都和某些指定点是联通的. 这道题比较简单的做法就是求出来所有的块.对于一个块,如果块里有两个及两个以上 ...

  6. [BZOJ2730][HNOI2012]矿场搭建(求割点)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2730 分析: 如果坍塌的点不是割点,那没什么影响,主要考虑坍塌的点是割点的情况. 显然 ...

  7. 【双连通分量】Bzoj2730 HNOI2012 矿场搭建

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

  8. BZOJ2730:[HNOI2012]矿场搭建(双连通分量)

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

  9. BZOJ2730 [HNOI2012]矿场搭建[点双连通分量]

    看到删去一个点,需要剩下的都和关键点连通,有端联想到找点双,因为他怎么删点都是连通的. 对于一个孤立的点双,至少要设两个关键点. 如果两个点双以一个割点连接,假设断掉这个割点,两个块至少要各设一个关键 ...

  10. [BZOJ2730]:[HNOI2012]矿场搭建(塔尖)

    题目传送门 题目描述 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖煤点设立救援出口,使得无论哪一个 ...

随机推荐

  1. Struts2动态方法调用(DMI)

    当structs.xml解析到Action的时候,默认执行的是此action的execute()方法,但是实际开发中,我们的action中含有很多方法,比如说增删改查的方法,那么structs.xml ...

  2. 夯实基础之php学习-2提高篇

    1,Jpgraph, 详见Php图形化jpgraph 2,文件系统 文件的操作步骤:打开文件->操作文件->关闭文件 打开文件fopen(filename,mode) 关闭文件fclose ...

  3. BZOJ 3110 【Zjoi2013】 K大数查询

    Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c如果是2 a b c形式,表示询问从第a个位置到第b个位置 ...

  4. 实现路由的RouterMiddleware中间件

    实现路由的RouterMiddleware中间件 虽然ASP.NET Core应用的路由是通过RouterMiddleware这个中间件来完成的,但是具体的路由解析功能都落在指定的Router对象上, ...

  5. QT QT练习一

    界面中通过三个 QLineEdit控件,一个QPushButton实现+ - * /四则运算,点击pushbutton后将运算结果显示在QLabel控件上. #ifndef WIDGET_H #def ...

  6. 为Visual Studio更换皮肤和背景图

    最近在博客上别人在老早之前就有加了背景图,想想怎么能这么out,于是乎,百度一下,能否知道? 咳咳,资源还是有滴!可惜都是比较旧的跟新版本的配置方法可能有点不一样, 可能会有很多人会觉得不适应,不过没 ...

  7. CSS 栅格布局

    bootstrap3.0教程之栅格系统原理(布局) http://www.jb51.net/css/152846.html [div+css]栅格化布局样式备用坑 http://www.0773lin ...

  8. 68 id -显示用户的id

    Linux id命令用于显示用户的ID,以及所属群组的ID. id会显示用户以及所属群组的实际与有效ID.若两个ID相同,则仅显示实际ID.若仅指定用户名称,则显示目前用户的ID. 语法 id [-g ...

  9. mysql安装方法

    Window版本 1.下载 MySQL Community Server 5.7.16 http://dev.mysql.com/downloads/mysql/ 2.解压 如果想要让MySQL安装在 ...

  10. 可以ping通,但是不能connect

    实测有效的解决方法: 通过minicom串口连接板子: su stop adbd start adbd 如果再不行,就在终端输入 adb kill-server adb start-server 参考 ...