HDU 3749 Financial Crisis 经济危机(点双连通分量)
题意:
给一个图n个点m条边(不一定连通),接下来又q个询问,询问两个点是为“不相连”,“仅有一条路径可达”,“有两条及以上的不同路径可达”三种情况中的哪一种。注:两条以上的路径指的是路径上的点连1个点也不重复。
思路:并查集+tarjan求割点。
(1)情况一:先并查集处理,如果两个点从一开始就不连通,直接输出zero
(2)情况二和情况三:两点既然连通,那么可能是只有1条路径,比如中间隔着一个割点;也可能有多条路径,比如在同一个双连通分量内。那么直接判断其是否在同一个双连通分量内即可,若在同一个双连通分量内,那么路径起码有2条不重复的。
并查集算法看其他题目。
tarjan用刘汝佳那个版本。只是我用了unordered_set来存储双连通分量,对于每个询问就在每个双连通分量中查是否同时存在(因为其中一个可能是割点),若同时存在且size>2才是输出 two or more。
具体实现看代码。
#include <bits/stdc++.h>
using namespace std;
const int N=+;
stack< pair<int,int> > stac; //tarjan用的栈
vector<int> vect[N]; //图
unordered_set<int> bi[N]; //双连通分量 int pre[N]; //并查集用的,保存领导 int find(int x) //查
{
return pre[x]==x? x: pre[x]=find(pre[x]);
} void joint(int x,int y) //并
{
x=find(x);
y=find(y);
if(x!=y) pre[x]=y;
} int dfn[N], low[N];
int bccno[N];
int cnter, bcc_cnt; void DFS(int x, int far)
{
dfn[x]= low[x]= ++cnter;
int chd=; //孩子
for(int i=; i<vect[x].size(); i++)
{
int t=vect[x][i]; if(!dfn[t]) //树边
{
chd++;
stac.push(make_pair(x,t)); //进栈
DFS(t,x);
low[x]=min(low[x],low[t]);
//if((far&&low[t]>=dfn[x]) || (!far&&chd>1) ) //割点
if(low[t]>=dfn[x] ) //割点。如果根只有0或1个孩子呢?那根就不是连通分量中的一个点。
{
bi[++bcc_cnt].clear(); //连通分量
while()
{
int a=stac.top().first;
int b=stac.top().second;
stac.pop();
if(bccno[a]!=bcc_cnt)
{
bccno[a]=bcc_cnt;
bi[bcc_cnt].insert(a);
}
if(bccno[b]!=bcc_cnt)
{
bccno[b]=bcc_cnt;
bi[bcc_cnt].insert(b);
}
if(a==x && b==t) break;
}
}
}
else if(dfn[t]<dfn[x] && t!=far)
{
stac.push(make_pair(x,t)); //进栈
low[x]=min(low[x],dfn[t]);
}
}
} int cal_bcc(int n)
{
memset(bccno,,sizeof(bccno));
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low)); while(!stac.empty()) stac.pop(); bcc_cnt= cnter=;
for(int i=n; i>; i--)
if(!dfn[i]) DFS(i,);
} int check(int n,int a, int b)
{
if(find(a)!=find(b)) return ; //不连通 for(int i=; i<=bcc_cnt; i++)
{
if(bi[i].find(a)!=bi[i].end() && bi[i].find(b)!=bi[i].end() && bi[i].size()>) //对于只有两个点的双连通分量,仅有1条边,输出one。
{
printf("two or more\n");
return ;
}
}
printf("one\n");
return ;
} void init(int n)
{
memset(pre,,sizeof(pre));
for(int i=; i<=n; i++) vect[i].clear();
for(int i=; i<=n; i++) pre[i]=i;
} int main()
{
freopen("input.txt", "r", stdin);
int n, m, q, a, b, j=;
while(scanf("%d%d%d",&n, &m, &q), n+m+q)
{
init(n);
for(int i=; i<m; i++)
{
scanf("%d%d", &a, &b);
vect[++a].push_back(++b);
vect[b].push_back(a);
joint(a,b); //并查集
} cal_bcc(n); //tarjan算法
printf("Case %d:\n",++j);
/*
for(int i=1; i<=bcc_cnt; i++) //输出每个双连通分量。
{
printf("第%d个双连通分量包含以下点:",i);
for(unordered_set<int>::iterator it=bi[i].begin(); it!=bi[i].end();it++)
{
printf("%d ",*it);
}
printf("\n");
}
*/
for(int i=; i<q; i++)
{
scanf("%d%d", &a, &b);
if(!check(n, ++a, ++b)) printf("zero\n");
}
}
return ;
}
AC代码
HDU 3749 Financial Crisis 经济危机(点双连通分量)的更多相关文章
- HDU 3749 Financial Crisis(点-双连通分量)
Because of the financial crisis, a large number of enterprises go bankrupt. In addition to this, oth ...
- HDU 3749 Financial Crisis (点双连通+并查集)
<题目连接> 题目大意: 给你一个(保证输入无重边,无自环)无向图,然后有下面Q条询问,每条询问为:问你u点与v点之间有几条(除了首尾两点外,其他点不重复)的路径.如果有0条或1条输出0或 ...
- HDU 3749 Financial Crisis
Financial Crisis 题意:给一个图,包含N ( 3 <= N <= 5000 )个点, M ( 0 <= M <= 10000 )条边 and Q ( 1 < ...
- HDU 4612——Warm up——————【边双连通分量、树的直径】
Warm up Time Limit:5000MS Memory Limit:65535KB 64bit IO Format:%I64d & %I64u Submit Stat ...
- Warm up HDU - 4612( 树的直径 边双连通分量)
求在图中新建一条边后 剩下的最少的桥的数量..先tarjan求桥的数量..然后缩点..以连通分量为点建图 bfs求直径 最后用桥的数量减去直径即为答案 bfs求直径 https://www.cnb ...
- hdu Caocao's Bridges(无向图边双连通分量,找出权值最小的桥)
/* 题意:给出一个无向图,去掉一条权值最小边,使这个无向图不再连同! tm太坑了... 1,如果这个无向图开始就是一个非连通图,直接输出0 2,重边(两个节点存在多条边, 权值不一样) 3,如果找到 ...
- HDU 5458 Stability(双连通分量+LCA+并查集+树状数组)(2015 ACM/ICPC Asia Regional Shenyang Online)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5458 Problem Description Given an undirected connecte ...
- HDU 2242 考研路茫茫——空调教室(边双连通分量+树形dp+重边标号)
http://acm.hdu.edu.cn/showproblem.php?pid=2242 题意: 思路:首先求一下双连通分量,如果只有一个双连通分量,那么无论断哪根管子,图还是连通的. 最后只需要 ...
- hdu 2460(tarjan求边双连通分量+LCA)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2460 思路:题目的意思是要求在原图中加边后桥的数量,首先我们可以通过Tarjan求边双连通分量,对于边 ...
随机推荐
- Ext学习-高级组件介绍
在这一部分的学习中,主要是学习一些比较特殊的组件. 1.图表 2.日历 3.颜色,日期,时间的选择器 4.滑动条 5.各种工具类 参考文档:http://docs.sencha.com/extjs/4 ...
- EXT经验--查询EditorGridPanel的tbar的默认配置对象
前言:EXT的API可谓熟悉EXT的葵花宝典,会看API可谓对于配置EXT,学习EXT最重要的基本功,这点相对于学习轻量级的Easyui来说更加明显. 比如下面的一段代码:注:在Ext.grid.Ed ...
- shell 循环使用
问题描述: shell中for循环while循环的使用 问题解决: (1)for循环 (1.1)数 ...
- uva 10304
最优二叉查找数 看了这位大牛 的博客 http://www.cnblogs.com/lpshou/archive/2012/04/26/2470914.html /****************** ...
- SpringMVC数据绑定全面示例(复杂对象,数组等)
点击链接查询原文 http://www.xdemo.org/springmvc-data-bind/ 已经使用SpringMVC开发了几个项目,平时也有不少朋友问我数据怎么传输,怎么绑定之类的话题,今 ...
- SDUT2142数据结构实验之图论二:基于邻接表的广度优先搜索遍历
http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=2142&cid=1186 题目描述 给定一个无向连通图,顶点编号从0到n-1,用广度优先搜 ...
- linux设置和查看环境变量的方法
1. 显示环境变量HOME $ echo $HOME /home/redbooks 2. 设置一个新的环境变量hello $ export HELLO="Hello!" ...
- lintcode:Coins in a Line 硬币排成线
题目 硬币排成线 有 n 个硬币排成一条线.两个参赛者轮流从右边依次拿走 1 或 2 个硬币,直到没有硬币为止.拿到最后一枚硬币的人获胜. 请判定 第一个玩家 是输还是赢? 样例 n = 1, 返回 ...
- java 泛型类
Java泛型中的标记符含义: E - Element (在集合中使用,因为集合中存放的是元素) T - Type(Java 类) K - Key(键) V - Value(值) N - Numbe ...
- Quartz的misfire特性
Quartz的misfire特性 只有一个线程.多个job 第一个job产生misfire(executeTime>Interval) 且是repeatForever 那么只会运行第一个job, ...