HDU 5222 ——Exploration——————【并查集+拓扑排序判有向环】
Exploration
Time Limit: 30000/15000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 194 Accepted Submission(s): 63
This labyrinth has N caves and some tunnels connecting some pairs of caves.
There are two types of tunnel, one type of them can be passed in only one direction and the other can be passed in two directions. Tunnels will collapse immediately after Miceren passing them.
Now, Miceren wants to choose a cave as his start point and visit at least one other cave, finally get back to start point.
As his friend, you must help him to determine whether a start point satisfing his request exists.
Each test case begins with three integers N, M1, M2, indicating the number of caves, the number of undirectional tunnels, the number of directional tunnels.
The next M1 lines contain the details of the undirectional tunnels. Each line contains two integers u, v meaning that there is a undirectional tunnel between u, v. (u ≠ v)
The next M2 lines contain the details of the directional tunnels. Each line contains integers u, v meaning that there is a directional tunnel from u to v. (u ≠ v)
T is about 100.
1 ≤ N,M1,M2 ≤ 1000000.
There may be some tunnels connect the same pair of caves.
The ratio of test cases with N > 1000 is less than 5%.
If you need a larger stack size,
please use #pragma comment(linker, "/STACK:102400000,102400000") and submit your solution using C++.
题目大意:给你n个山洞,m1条无向隧道,m2条有向隧道,要你从一个山洞出发,经过除出发点外至少一个山洞回到出发点,一条隧道经过后会坍塌,问是否存在满足要求的路径。
解题思路:
首先对于所有的无向边,我们使用并查集将两边的点并起来。
若一条边未合并之前,两端的点已经处于同一个集合了,那么说明必定存在可行的环(因为这两个点处于同一个并查集集合中,那么它们之间至少存在一条路径)
如果上一步没有判断出环,那么仅靠无向边是找不到环的
考虑到,处于同一个并查集集合中的点之间必定存在一条路径互达,因此将一个集合的点合并之后(利用缩点),原问题等价于在新生成的有向图中是否有环
我们知道,有向无环图必定存在拓扑序,因此只需使用拓扑排序判定即可
时间复杂度O(N+M1+M2)
#include<stdio.h>
#include<string.h>
#include<vector>
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
int n,m1,m2;
const int maxn=1e6+666;
int fa[maxn]; //并查集的father数组
bool flag[maxn]; //标记缩点、不重复加入队列
int indeg[maxn]; //记录入度
vector<int>Mp[maxn];//存有向边
int Find(int x){
return fa[x]=fa[x]==x?x:Find(fa[x]);
}
bool Union(int x,int y){
int fx,fy;
fx=Find(x);
fy=Find(y);
if(fx<fy){
fa[fy]=fx;
}else if(fx>fy){
fa[fx]=fy;
}else{ //如果该无向边的两端同属一个集合,加入该边后,肯定形成环
return true;
}
return false;
}
bool u_f_set(){
for(int i=1;i<=n;i++) //初始化fa
fa[i]=i;
bool cir=0; //是否形成环
for(int i=0;i<m1;i++){
int u,v;
scanf("%d %d",&u,&v);
if(!cir&&Union(u,v)) //如果形成环,只需输入,不操作
cir=1;
}
return cir;
}
bool topo_sort(){
for(int i=0;i<=n;i++)
Mp[i].clear();
memset(indeg,0,sizeof(indeg));
memset(flag,0,sizeof(flag));
bool cir=0; //初始化
for(int i=0;i<m2;i++){
int u,v,fu,fv;
scanf("%d%d",&u,&v);
if(cir==1) //如果已经有环,只需输入
continue;
fu=Find(u);
fv=Find(v);
if(fu==fv){ //如果有向边两个端点在一个集合(缩点)中,必成环
cir=1;
}else{
Mp[fu].push_back(fv); //存有向边
indeg[fv]++; //该集合(缩点)入度加一
}
}
if(cir==1){
return 1;
}else{
queue<int>Q;
while(!Q.empty())
Q.pop();
int cnt_c=0;
for(int i=1;i<=n;i++){
int i_f=Find(i);
if(i_f==i){
cnt_c++; //记录所有集合(缩点)个数
}
if(indeg[i_f]==0&&flag[i_f]==0){ //该集合(缩点)入度为零,且未加入队列
Q.push(i_f);
flag[i_f]=1;
}
}
int cnt=0;
while(!Q.empty()){ //bfs_topo排序
int u=Q.front();
cnt++; //记录拓扑排序排了多少个集合(缩点)
Q.pop();
for(int i=0;i<Mp[u].size();i++){
int j=Mp[u][i];
indeg[j]--;
if(indeg[j]==0&&flag[j]==0){
Q.push(j);
flag[j]=1;
}
}
}
if(cnt_c==cnt){ //如果总的集合个数等于拓扑排序的集合个数,说明无环
return false;
}else{
return true;
}
}
}
int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d%d",&n,&m1,&m2);
if(u_f_set()){
for(int i=0;i<m2;i++){
int u,v;
scanf("%d%d",&u,&v);
}printf("YES\n");
}
else{
if(topo_sort()) printf("YES\n");
else printf("NO\n");
}
}
} /* 55
3 1 1
1 3
3 2
NO
4 2 2
1 2
2 3
4 3
4 1
NO
7 3 4
2 1
1 7
3 4
6 3
5 6
4 5
7 6
YES
4 1 3
4 1
3 2
4 3
4 1
YES
7 2 3
1 2
2 3
4 5
5 6
6 4
YES
9 4 4
1 2
1 7
3 4
8 9
7 6
5 6
4 5
6 3
YES
*/
HDU 5222 ——Exploration——————【并查集+拓扑排序判有向环】的更多相关文章
- HDU 1811(并查集+拓扑排序)题解
Problem Description 自从Lele开发了Rating系统,他的Tetris事业更是如虎添翼,不久他遍把这个游戏推向了全球.为了更好的符合那些爱好者的喜好,Lele又想了一个新点子:他 ...
- 并查集+拓扑排序 赛码 1009 Exploration
题目传送门 /* 题意:无向图和有向图的混合图判环: 官方题解:首先对于所有的无向边,我们使用并查集将两边的点并起来,若一条边未合并之前, 两端的点已经处于同一个集合了,那么说明必定存在可行的环(因为 ...
- HDU 1811:Rank of Tetris(并查集+拓扑排序)
http://acm.hdu.edu.cn/showproblem.php?pid=1811 Rank of Tetris Problem Description 自从Lele开发了Rating系 ...
- hdu 1811Rank of Tetris (并查集 + 拓扑排序)
/* 题意:这些信息可能有三种情况,分别是"A > B","A = B","A < B",分别表示A的Rating高于B,等于B ...
- HDU 1811 Rank of Tetris(并查集+拓扑排序 非常经典)
Rank of Tetris Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- HDU——1272小希的迷宫(并查集+拓扑排序)
小希的迷宫 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Subm ...
- 【并查集+拓扑排序】【HDU1811】【Rank of Tetris】
题意:给你3种关系 A=B,A>B,A<B 问是否排名方式唯一,或者存在矛盾 解 1.读入数据先处理 =号 用并查集的祖先作为代表元素,其他儿子节点都等于跟这个点重叠. 再读入 '< ...
- Codeforces Round #541 (Div. 2) D(并查集+拓扑排序) F (并查集)
D. Gourmet choice 链接:http://codeforces.com/contest/1131/problem/D 思路: = 的情况我们用并查集把他们扔到一个集合,然后根据 > ...
- Codeforces Round #541 (Div. 2) D 并查集 + 拓扑排序
https://codeforces.com/contest/1131/problem/D 题意 给你一个n*m二维偏序表,代表x[i]和y[j]的大小关系,根据表构造大小分别为n,m的x[],y[] ...
随机推荐
- WPF 控件库——轮播控件
WPF 控件库系列博文地址: WPF 控件库——仿制Chrome的ColorPicker WPF 控件库——仿制Windows10的进度条 WPF 控件库——轮播控件 WPF 控件库——带有惯性的Sc ...
- Go环境搭建(Windows)
下载MSI MSI地址 配置环境变量 GOPATH: 用于存放Go语言Package的目录,这个目录不能在Go的安装目录中 GOBIN: Go二进制文件存放目录,写成%GOROOT%\bin就好 PA ...
- vi—终端中的编辑器
*:first-child { margin-top: 0 !important; } .markdown-body>*:last-child { margin-bottom: 0 !impor ...
- 渗透测试工具实战技巧 (转载freebuf)
最好的 NMAP 扫描策略 # 适用所有大小网络最好的 nmap 扫描策略 # 主机发现,生成存活主机列表 $ nmap -sn -T4 -oG Discovery.gnmap 192.168.56. ...
- win10 + Lubuntu 双系统安装
win10 + Lubuntu 双系统安装 最近重装了系统,索性直接安装win10 + Lubuntu 双系统,便于在物理机下进行 Linux开发. 这里我选择的 Linux 发行版是 Lubuntu ...
- Python实现——二次多项式回归(最小二乘法)
2019/3/25 真的,当那个图像出现的时候,我真的感觉太美了. 或许是一路上以来自我的摸索加深的我对于这个模型的感受吧. 二次函数拟合--最小二乘法公式法 与线性回归相似,对二次函数进行拟合某种意 ...
- Python3之json模块
概念: 序列化(Serialization):将对象的状态信息转换为可以存储或可以通过网络传输的过程,传输的格式可以是JSON,XML等.反序列化就是从存储区域(JSON,XML)读取反序列化对象的状 ...
- Spring Cloud-服务的注册与发现之服务注册中心(Eureka Server)
Spring cloud是为了什么产生的? 根据官网的这个介绍来看,我们可以知道,Spring cloud是为开发者提供的一个工具,而使用这个工具的产生就是为了帮助开发者快速的开发一套比较通用的分布式 ...
- flask_restful
from flask_restful import (Resource, reqparse) # 参数解析对象生成 parser = reqparse.RequestParser() parser.a ...
- sharepoint_study_3
SharePoint网页无法打开 描述:安装部署好SharePoint开发环境后,再修改计算机的机器名,重启计算机后,发现SharePoint网站不能打开. 解决:1.将机器名改回去,重启计算机,问题 ...