题意:

  给一个图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 经济危机(点双连通分量)的更多相关文章

  1. HDU 3749 Financial Crisis(点-双连通分量)

    Because of the financial crisis, a large number of enterprises go bankrupt. In addition to this, oth ...

  2. HDU 3749 Financial Crisis (点双连通+并查集)

    <题目连接> 题目大意: 给你一个(保证输入无重边,无自环)无向图,然后有下面Q条询问,每条询问为:问你u点与v点之间有几条(除了首尾两点外,其他点不重复)的路径.如果有0条或1条输出0或 ...

  3. HDU 3749 Financial Crisis

    Financial Crisis 题意:给一个图,包含N ( 3 <= N <= 5000 )个点, M ( 0 <= M <= 10000 )条边 and Q ( 1 < ...

  4. HDU 4612——Warm up——————【边双连通分量、树的直径】

    Warm up Time Limit:5000MS     Memory Limit:65535KB     64bit IO Format:%I64d & %I64u Submit Stat ...

  5. Warm up HDU - 4612( 树的直径 边双连通分量)

    求在图中新建一条边后  剩下的最少的桥的数量..先tarjan求桥的数量..然后缩点..以连通分量为点建图  bfs求直径 最后用桥的数量减去直径即为答案 bfs求直径 https://www.cnb ...

  6. hdu Caocao's Bridges(无向图边双连通分量,找出权值最小的桥)

    /* 题意:给出一个无向图,去掉一条权值最小边,使这个无向图不再连同! tm太坑了... 1,如果这个无向图开始就是一个非连通图,直接输出0 2,重边(两个节点存在多条边, 权值不一样) 3,如果找到 ...

  7. 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 ...

  8. HDU 2242 考研路茫茫——空调教室(边双连通分量+树形dp+重边标号)

    http://acm.hdu.edu.cn/showproblem.php?pid=2242 题意: 思路:首先求一下双连通分量,如果只有一个双连通分量,那么无论断哪根管子,图还是连通的. 最后只需要 ...

  9. hdu 2460(tarjan求边双连通分量+LCA)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2460 思路:题目的意思是要求在原图中加边后桥的数量,首先我们可以通过Tarjan求边双连通分量,对于边 ...

随机推荐

  1. Ext学习-HelloWorld以及基础环境搭建

    1.目的    在eclipse中搭建EXTJS的基础环境,学习如何按照从官方下载的代码中搭建新的Extjs工程 2.主要包含内容:   1.ExtJS文件下载以及目录说明   2.ExtJS开发环境 ...

  2. JQuery图片延迟加载插件,动态获取图片长宽尺寸

    以前的网站带宽小,没有特别多的大图,现在不同了,各种图片网站如同雨后春笋层出不穷.服务器是抗住了,但是客户端就有意见了,太多的图片必然导致页面加载缓慢,特别是有些table结构的站点更是如此.能否让图 ...

  3. apache 多域名配置

    一直不明白apache多域名配置的问题,所以只能用不同的端口来配置,现在终于搞懂了一点 首先,开启apache的vhost模块 找到配置文件httpd.conf中的下面两行 #LoadModule v ...

  4. mysql 误删除ibdata1之后如何恢复

    mysql 误删除ibdata1之后如何恢复 如果误删除了在线服务器中mysql innodb相关的数据文件ibdata1以及日志文件 ib_logfile*,应该怎样恢复呢? 这时候应该一身冷汗了吧 ...

  5. C#的cs文件中Response.Clear();Response.ClearHeaders()的作用

    在学习一个CS文件,如下:public partial class GetPic : System.Web.UI.Page{    protected void Page_Load(object se ...

  6. 【转载】SSH框架总结(将网上朋友写的给整合了下)

    一.Struts 在没有学习SSH框架前,我们一般采用Jsp+javabean+servlet开发,这里就是MVC架构.而Struts其实就是替代了Servlet,我们知道Servlet在一般的开发中 ...

  7. nmap使用详解

    nmap是一个网络探测和安全扫描程序, 系统管理者和个人可以使用这个软件扫描大型的网络,获取那台主机正在运行以及提供什么服务等信息.nmap支持很多扫描技术,例如:UDP.TCP connect(). ...

  8. Hadoop-eclipse-plugin插件安装

    Hadoop-eclipse-plugin插件安装 学习Hadoop有一段时间了,以前每次的做法都是先在win下用eclipse写好Mapreduce程序,然后打成jar文件,上传到linux下用ha ...

  9. BZOJ 3129 SDOI2013 方程

    如果没有限制,答案直接用隔板法C(m-1,n-1) 对于>=x的限制,我们直接在对应位置先放上x-1即可,即m=m-(x-1) 对于<=x的限制,由于限制很小我们可以利用容斥原理将它转化为 ...

  10. sparse coding稀疏表达入门

    最近在看sparse and redundant representations这本书,进度比较慢,不过力争看过的都懂,不把时间浪费掉.才看完了不到3页吧,书上基本给出了稀疏表达的概念以及传统的求法. ...