bzoj2730矿场搭建(Tarjan割点)
2730: [HNOI2012]矿场搭建
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 1771 Solved: 835
[Submit][Status][Discuss]
Description
Input
输入文件有若干组数据,每组数据的第一行是一个正整数 N(N≤500),表示工地的隧道数,接下来的 N 行每行是用空格隔开的两个整数 S 和 T,表示挖 S 与挖煤点 T 由隧道直接连接。输入数据以 0 结尾。
Output
输入文件中有多少组数据,输出文件 output.txt 中就有多少行。每行对应一组输入数据的 结果。其中第 i 行以 Case i: 开始(注意大小写,Case 与 i 之间有空格,i 与:之间无空格,: 之后有空格),其后是用空格隔开的两个正整数,第一个正整数表示对于第 i 组输入数据至少需 要设置几个救援出口,第二个正整数表示对于第 i 组输入数据不同最少救援出口的设置方案总 数。输入数据保证答案小于 2^64。输出格式参照以下输入输出样例。
Sample Input
1 3
4 1
3 5
1 2
2 6
1 5
6 3
1 6
3 2
6
1 2
1 3
2 4
2 5
3 6
3 7
Sample Output
Case 2: 4 1
HINT
- /*
- 首先看到割点就是Tarjan搞 但是怎么搞
- 首先假设我们把所有的点双都缩点 那么我们一定可以得到一棵树 然后我们就会发现
- 1.叶子节点(只含有一个割点的点双)必须建 因为叶子节点如果不建 一旦割点被爆就死翘了
- 2.非叶节点(含有两个或两个以上的割点的点双)不用建 因为即使一个割点被爆了也可以沿着另一个割点走到一个叶节点
- 3.还有一种情况就是整个联通块都是点双(即不含割点的点双) 这样我们讨论点双的大小
- 如果只有一个点 那么这个点必须建 数据没有卡这个的点所以我没写(其实是我忘写了 然后还过了)
- 如果有两个或两个以上的点 那么要建两个 一个被爆了还可以走另一个
- 方案数就是乘法原理的问题了 注意叶节点那里出口不能建在割点上
- 所以先Tarjan求割点再dfs一下每个联通块就好了。
- */
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- #define ll long long
- using namespace std;
- int head[],dfn[],low[],vis[],stack[];
- bool cut[],in_stack[];
- int n,m,cnt,num,tot,deg,ans1,T,cases,root,top;
- ll ans2;
- struct node
- {
- int from;
- int to;
- int next;
- }e[];
- inline void first()
- {
- memset(head,,sizeof(head));
- memset(dfn,,sizeof(dfn));
- memset(low,,sizeof(low));
- memset(cut,,sizeof(cut));
- memset(vis,,sizeof(vis));
- top=cnt=tot=n=ans1=T=; ans2=;
- }
- inline void insert(int from,int to)
- {
- e[++num].from=from;
- e[num].to=to;
- e[num].next=head[from];
- head[from]=num;
- }
- inline int read()
- {
- int x=,f=; char c=getchar();
- while (c<''||c>''){if(c=='-')f=-;c=getchar();}
- while (c>=''&&c<=''){x=x*+c-'';c=getchar();}
- return x*f;
- }
- void Tarjan(int now,int father)//求割点
- {
- dfn[now]=low[now]=++tot;
- for(int i=head[now];i;i=e[i].next)
- {
- int v=e[i].to;
- if(!dfn[v])
- {
- Tarjan(v,now);
- low[now]=min(low[now],low[v]);
- if(low[v]>=dfn[now])
- {
- if(now==root) deg++;
- else cut[now]=true;
- }
- }
- else if(v!=father) low[now]=min(low[now],dfn[v]);//不要跟求环混了 具体原理去网上找
- }
- }
- void dfs(int x)//遍历每个连通块
- {
- vis[x]=T;//标记
- if(cut[x]) return;
- cnt++;//数量
- for(int i=head[x];i;i=e[i].next)
- {
- int v=e[i].to;
- if(cut[v]&&vis[v]!=T) num++,vis[v]=T;//统计割点数目。
- //如果是割点且标记不与遍历的的连通块相同就修改标记。
- if(!vis[v])dfs(v);
- }
- }
- int main()
- {
- m=read();
- while (m)
- {
- first();
- for (int i=;i<=m;i++)
- {
- int u=read(),v=read();
- n=max(n,max(u,v));//这个地方要处理一下
- insert(u,v); insert(v,u);
- }
- for (int i=;i<=n;i++)
- {
- if (!dfn[i]) Tarjan(root=i,);
- if (deg>=) cut[root]=;//根节点的割点
- deg=;//不要忘记是多组数据
- }
- for (int i=;i<=n;i++)
- if (!vis[i]&&!cut[i])//不是割点
- {
- T++; cnt=num=;//T为连通块的标记
- dfs(i);
- if (!num) ans1+=,ans2*=cnt*(cnt-)/;//建两个 别忘记除以二 因为两个建立的出口没有差异
- if (num==) ans1++,ans2*=cnt;//建一个
- }
- printf("Case %d: %d %lld\n",++cases,ans1,ans2);
- m=read();
- }
- return ;
- }
bzoj2730矿场搭建(Tarjan割点)的更多相关文章
- BZOJ2730 [HNOI2012]矿场搭建 - Tarjan割点
Solution 输入中没有出现过的矿场点是不用考虑的, 所以不用考虑只有 一个点 的点双联通分量. 要使某个挖矿点倒塌, 相当于割去这个点, 所以我们求一遍割点和点双联通分量. 之后的点双联通分量构 ...
- P3225 [HNOI2012]矿场搭建 tarjan割点
这个题需要发现一点规律,就是先按割点求块,然后求每个联通块中有几个割点,假如没有割点,则需要建两个出口,如果一个割点,则需要建一个出口,2个以上不用建. 题干: 题目描述 煤矿工地可以看成是由隧道连接 ...
- 【BZOJ2730】[HNOI2012]矿场搭建 Tarjan
[BZOJ2730][HNOI2012]矿场搭建 Description 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处. ...
- 【BZOJ-2730】矿场搭建 Tarjan 双连通分量
2730: [HNOI2012]矿场搭建 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1602 Solved: 751[Submit][Statu ...
- BZOJ 2730: [HNOI2012]矿场搭建( tarjan )
先tarjan求出割点.. 割点把图分成了几个双连通分量..只需dfs找出即可. 然后一个bcc有>2个割点, 那么这个bcc就不用建了, 因为一定可以走到其他救援出口. 只有一个割点的bcc就 ...
- BZOJ 2730:[HNOI2012]矿场搭建(割点+连通块)
[HNOI2012]矿场搭建 Description 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖 ...
- [HNOI2012]矿场搭建(割点)
[HNOI2012]矿场搭建 题目描述 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖煤点设立救援出 ...
- BZOJ 2730 矿场搭建 Tarjan求割点
思路: Tarjan求出来点双&割点 判一判就行了 //By SiriusRen #include <stack> #include <cstdio> #include ...
- bzoj 2730: [HNOI2012]矿场搭建——tarjan求点双
Description 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖煤点设立救援出口,使得无论哪一 ...
随机推荐
- 低版本ie兼容问题的解决方案
CSS hack \9 所有的IE10及之前 * IE7以及IE7以下版本的 _ IE6以及IE6以下版本的 !important 提升样式优先级权重 1.ie6,7 ...
- jsonview插件的常见使用方法整理
Jsonview是目前最热门的一款开发者工具插件,确切的来说jQuery JSONView是一款非常实用的格式化和语法高亮JSON格式数据查看器jQuery插件.它是查看json数据的神器. 下载地址 ...
- Python-组合数据类型
集合类型及操作 >集合类型定义 集合是多个元素的无序组合 -集合类型与数学中的集合概念一致 -集合元素之间无序,每个元素唯一,不存在相同元素 -集合元素不可更改,不能是可变数据类型 -集合用大括 ...
- Cmake的介绍和使用 Cmake实践
Cmake的介绍和使用 Cmake实践http://www.cppblog.com/Roger/archive/2011/11/17/160368.html
- accept阻塞
一直以来以为accept阻塞的时候,若另有线程关闭相应的监听套接字,accept会立即返回. 今天先是在NDK上试,没反应.又在ARCHLINUX试了下,还是没反应.难道是我一直记的都是错的!!!!! ...
- [luoguP1111] 修复公路(并查集)
传送门 呵呵的最小生成树 ——代码 #include <cstdio> #include <iostream> #include <algorithm> #defi ...
- 如何将jsp后缀重写为html
公司有时候要写一些小的项目,而用java搭建web的一个缺(特)陷(征)就是动态网页的后缀名.jsp.没办法啊,就是不能以.jsp结尾,原因有几个:隐藏服务端技术:吸引爬虫:对用户更友好:等等.如果全 ...
- MYSQL常用的时间日期函数
#时间日期函数 #获取当前日期XXXX-XX-XXSELECT CURRENT_DATE(); SELECT CURDATE();#效果与上一条相同 #获取当前日期与时间XXXX-XX-XX XX:X ...
- Drools等规则引擎技术对比分析
项目中需要设计开发一个规则引擎服务,于是调研了业界常用的规则引擎. 常见的规则引擎如下: Ilog JRules 是最有名的商用BRMS: Drools 是最活跃的开源规则引擎: Jess 是Clip ...
- HTML表单数据转JSON
问题描述 后端使用如下方式接收前端传入参数: @PostMapping(value = "/test", produces = MediaType.APPLICATION_JSON ...