并查集+拓扑排序 赛码 1009 Exploration
- /*
- 题意:无向图和有向图的混合图判环;
- 官方题解:首先对于所有的无向边,我们使用并查集将两边的点并起来,若一条边未合并之前,
- 两端的点已经处于同一个集合了,那么说明必定存在可行的环(因为这两个点处于同一个并查集集合中,那么它们之间至少存在一条路径)
- 如果上一步没有判断出环,那么仅靠无向边是找不到环的
- 考虑到,处于同一个并查集集合中的点之间必定存在一条路径互达,因此将一个集合的点合并之后,
- 原问题等价于在新生成的有向图中是否有环
- 我们知道,有向无环图必定存在拓扑序,因此只需使用拓扑排序判定即可
- 时间复杂度O(N+M1+M2)
- 并查集+拓扑排序:并查集来判断无向图,拓扑排序判断有向图
- 另外:用读入外挂时间比scanf ()多,不清楚...
- Accepted 5222 5007MS 45124K 2158 B G++ BH //scanf ()
- Accepted 5222 7581MS 45116K 2158 B G++ BH //read ()
- */
- #include <cstdio>
- #include <cmath>
- #include <cstring>
- #include <string>
- #include <iostream>
- #include <algorithm>
- #include <queue>
- #include <vector>
- #pragma comment(linker, "/STACK:102400000,102400000")
- using namespace std;
- const int MAXN = 1e6 + ;
- const int INF = 0x3f3f3f3f;
- int ans[MAXN], in[MAXN];
- int rt[MAXN];
- vector<int> G[MAXN];
- int n, m1, m2;
- inline int read(void)
- {
- int x = , f = ; char ch = getchar ();
- while (ch < '' || ch > '') {if (ch == '-') f = -; ch = getchar ();}
- while (ch >= '' && ch <= '') {x = x * + ch - ''; ch = getchar ();}
- return x * f;
- }
- bool TopoSort(void)
- {
- memset (in, , sizeof (in));
- for (int i=; i<=n; ++i)
- for (int j=; j<G[i].size (); ++j) in[G[i][j]]++;
- queue<int> Q; int cnt = ;
- for (int i=; i<=n; ++i) {if (!in[i]) Q.push (i);}
- while (!Q.empty ())
- {
- int u = Q.front (); Q.pop ();
- ans[++cnt] = u;
- for (int j=; j<G[u].size (); ++j)
- {
- int v = G[u][j];
- in[v]--;
- if (!in[v]) Q.push (v);
- }
- }
- if (cnt == n) return false;
- else return true;
- }
- int Find(int x)
- {
- return (rt[x] == x) ? rt[x] : rt[x] = Find (rt[x]);
- }
- void Union(int x, int y)
- {
- x = Find (x); y = Find (y);
- if (x < y) rt[x] = y;
- else rt[y] = x;
- }
- bool same(int x, int y)
- {
- return (Find (x) == Find (y)) ? true : false;
- }
- int main(void) //赛码 1009 Exploration
- {
- //freopen ("I.in", "r", stdin);
- int t;
- scanf ("%d", &t);
- while (t--)
- {
- scanf ("%d%d%d", &n, &m1, &m2);
- for (int i=; i<=n; ++i) rt[i] = i;
- for (int i=; i<=n; ++i) G[i].clear ();
- bool ok = false; int u, v;
- for (int i=; i<=m1; ++i)
- {
- scanf ("%d%d", &u, &v);
- //u = read (); v = read ();
- //G[u].push_back (v);
- if (same (u, v) == true) ok = true;
- else Union (u, v);
- }
- for (int i=; i<=m2; ++i)
- {
- int u, v;
- scanf ("%d%d", &u, &v);
- //u = read (); v = read ();
- if (same (u, v) == true) ok = true;
- if (ok) continue;
- G[u].push_back (v);
- }
- if (ok) {puts ("YES"); continue;}
- if (TopoSort () == true) puts ("YES");
- else puts ("NO");
- }
- return ;
- }
并查集+拓扑排序 赛码 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 ...
- 【并查集+拓扑排序】【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[] ...
- HDU 1811 Rank of Tetris(并查集+拓扑排序 非常经典)
Rank of Tetris Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- HDU 1811(并查集+拓扑排序)题解
Problem Description 自从Lele开发了Rating系统,他的Tetris事业更是如虎添翼,不久他遍把这个游戏推向了全球.为了更好的符合那些爱好者的喜好,Lele又想了一个新点子:他 ...
- HDU 5222 ——Exploration——————【并查集+拓扑排序判有向环】
Exploration Time Limit: 30000/15000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)T ...
- HDU——1272小希的迷宫(并查集+拓扑排序)
小希的迷宫 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Subm ...
随机推荐
- dedecms删除没有文章的标签
要批量的删除织梦TAG标签,那我们就只能在数据库里做修改了. 登录数据库,在数据库里执行以下SQL语句: delete FROM dede_tagindex where typeid not in ( ...
- Linux简单的常用命令——纯手打(慢慢积累)
==============linux下快捷键==================ctrl+insert 复制shift +insert 粘贴 输入文件名的前三个字母,按tab键自动补全文件名 在vi ...
- SVN安装与配置 SVN整合MyEclipse
SVN安装: 1.安装服务器 ######### 安装文件:SVN服务器############### # http://www.collab.net/downloads/subversion # C ...
- Metasploit是一款开源的安全漏洞检测工具,
Metasploit是一款开源的安全漏洞检测工具,可以帮助安全和IT专业人士识别安全性问题,验证漏洞的缓解措施,并管理专家驱动的安全性进行评估,适合于需要核实漏洞的安全专家,同时也适合于强大进攻能力的 ...
- #define 的一些用法 以及 迭代器的 [] 与 find()函数的区别
#include "stdafx.h" #include <map> #include <string> #include <iostream> ...
- C++ virtual descructor
[代码1] C++ Code 12345678910111213141516171819202122232425262728293031323334353637383940414243444546 ...
- object-c学习笔记
原文地址 最近开始学习object-c,分享一下学习oc的经验以及对oc的理解,其中难免会有错误,请大家理解. 对初学者来说,objective-c存在了很多令人费解的写法,当然也包括我! 我刚开始看 ...
- css3学习总结1--CSS3选择器
CSS3的属性选择器主要包括以下几种: 1. E[attr^="value"]:指定了属性名,并且有属性值,属性值是以value开头的: 2. E[attr$="valu ...
- Google map测量工具
启用Google map的测量工具,测量图上的距离. 打开Google map,左下角看到Google 地图实验室,点开,然后enable相应功能即可. 通过Google map lab还能使我们能够 ...
- 核电站问题(codevs 2618)
题目描述 Description 一个核电站有N个放核物质的坑,坑排列在一条直线上.如果连续M个坑中放入核物质,则会发生爆炸,于是,在某些坑中可能不放核物质. 任务:对于给定的N和M,求不发生爆炸的放 ...