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求边双连通分量,对于边 ...
随机推荐
- springMVC+ibatis数据持久化入门级学习例子
1.web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app version=" ...
- 数组对象Vector用法
import java.util.Vector; public class VectorTesting { public static void main(String[] args) { Vecto ...
- POJ2217 Secretary 后缀数组&&高度数组
学后缀数组后的一道裸题.先来讲讲收获,作为字符串初学者,后缀数组也是刚刚在学,所幸的是有一篇好的论文<后缀数组--处理字符串的有力工具>by 罗穗骞,里面非常详尽地介绍了有关后缀数组的概念 ...
- 【leetcode】Median of Two Sorted Arrays(hard)★!!
There are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted ...
- 1034-IBM技术俱乐部主席竞选
描述 今天IBM技术俱乐部举行主席竞选,你的任务是统计谁是得票最多的候选人. 输入 输入数据包含多组测试案例. 每组测试案例由N(0<N<1000)开头,N表示投票总数,后续N行每行包含一 ...
- HDU 3507 Print Article(斜率优化DP)
题目链接 题意 : 一篇文章有n个单词,如果每行打印k个单词,那这行的花费是,问你怎么安排能够得到最小花费,输出最小花费. 思路 : 一开始想的简单了以为是背包,后来才知道是斜率优化DP,然后看了网上 ...
- 能量项链//区间DP
P1056 能量项链 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 NOIP2006 提高组 第一道 描述 在Mars星球上,每个Mars人都随身佩 ...
- [hackerrank]Service Lane
https://www.hackerrank.com/challenges/service-lane 用RMQ做的,其实暴力也能过~ #include <iostream> #includ ...
- PHP中的多态
多态的概念一般是强类型语言来谈的,因为强类型语言它必须要声明参数类型,比如一个手电筒对象的打开方法其参数申明了只能是蓝光,就不能传其他光.但可以用父类渲染的方式使其多态,比如声明一个光的父类,让其它颜 ...
- Apache源码分析资源
关于作者张中庆, 目前主要的研究方向是嵌入式浏览器,移动中间件以及大规模服务器设计.目前正在进行Apache的源代码分析,计划出版<Apache源代码全景分析>上 下册.Apache系列文 ...