POJ 2762 Going from u to v or from v to u? (强连通分量缩点+拓扑排序)
题目链接:http://poj.org/problem?id=2762
题意是 有t组样例,n个点m条有向边,取任意两个点u和v,问u能不能到v 或者v能不能到u,要是可以就输出Yes,否则输出No。注意一点,条件是或者!所以不是判断双连通图的问题。
我一开始没看到'or'这个条件,所以直接tarjan判断是否只有一个强连通分量,果断WA。
所以需要给原图缩点,用tarjan把图变成一个有向无环图,要是只有一个scc,那就直接输出Yes。那接下来讨论多个scc,要是新图中有两个及以上的点的入度为0,则这些点都不能相互到达,所以输出No,所以我们找到唯一一个入度为0的点作为root,然后从这个点来拓扑排序,出队入队的过程肯定是一进一出的,所以根据过程来判断是否输出Yes和No。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
const int MAXN = ;
struct data {
int next , to;
}edge[MAXN * ];
int head[MAXN] , st[MAXN] , low[MAXN] , dfn[MAXN] , block[MAXN] , du[MAXN];
int top , ord , sccnum , cont;
bool instack[MAXN];
vector <int> G[MAXN]; inline void add(int u , int v) {
edge[cont].next = head[u];
edge[cont].to = v;
head[u] = cont++;
} void init() {
memset(head , - , sizeof(head));
memset(dfn , , sizeof(dfn));
memset(du , , sizeof(du));
memset(instack , false , sizeof(instack));
top = sccnum = ord = cont = ;
} void tarjan(int u) {
low[u] = dfn[u] = ++ord;
st[++top] = u;
instack[u] = true;
for(int i = head[u] ; ~i ; i = edge[i].next) {
int v = edge[i].to;
if(!dfn[v]) {
tarjan(v);
low[u] = min(low[u] , low[v]);
}
else if(instack[v]) {
low[u] = min(low[u] , low[v]);
}
}
if(low[u] == dfn[u]) {
int v;
sccnum++;
do {
v = st[top--];
instack[v] = false;
block[v] = sccnum;
}while(u != v);
}
} void top_sort() {
queue <int> que;
while(!que.empty()) {
que.pop();
}
cont = ;
for(int i = ; i <= sccnum ; i++) {
if(!du[i]) {
que.push(i);
cont++;
}
}
if(cont > ) {
printf("No\n");
return ;
}
while(!que.empty()) {
int temp = que.front() , cnt = ;
que.pop();
for(int i = ; i < G[temp].size() ; i++) {
du[G[temp][i]]--;
if(!du[G[temp][i]]) {
cnt++;
cont++;
que.push(G[temp][i]);
}
}
if(cnt > ) {
printf("No\n");
return ;
}
}
if(cont != sccnum) {
printf("No\n");
}
else {
printf("Yes\n");
}
} int main()
{
int t , n , m , u , v;
scanf("%d" , &t);
while(t--) {
scanf("%d %d" , &n , &m);
init();
for(int i = ; i < m ; i++) {
scanf("%d %d" , &u , &v);
add(u , v);
}
for(int i = ; i <= n ; i++) {
G[i].clear();
if(!dfn[i])
tarjan(i);
}
if(sccnum == ) {
printf("Yes\n");
continue;
}
for(int u = ; u <= n ; u++) {
for(int i = head[u] ; ~i ; i = edge[i].next) {
int v = edge[i].to;
if(block[u] != block[v]) {
du[block[v]]++;
G[block[u]].push_back(block[v]);
}
}
}
top_sort();
}
}
POJ 2762 Going from u to v or from v to u? (强连通分量缩点+拓扑排序)的更多相关文章
- poj 2762 Going from u to v or from v to u?【强连通分量缩点+拓扑排序】
Going from u to v or from v to u? Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 15812 ...
- POJ2762 Going from u to v or from v to u? 强连通分量缩点+拓扑排序
题目链接:https://vjudge.net/contest/295959#problem/I 或者 http://poj.org/problem?id=2762 题意:输入多组样例,输入n个点和m ...
- POJ2762 Going from u to v or from v to u?(判定单连通图:强连通分量+缩点+拓扑排序)
这道题要判断一张有向图是否是单连通图,即图中是否任意两点u和v都存在u到v或v到u的路径. 方法是,找出图中所有强连通分量,强连通分量上的点肯定也是满足单连通性的,然后对强连通分量进行缩点,缩点后就变 ...
- poj 2762 Going from u to v or from v to u?(强连通分量+缩点重构图+拓扑排序)
http://poj.org/problem?id=2762 Going from u to v or from v to u? Time Limit: 2000MS Memory Limit: ...
- 【强连通分量缩点】poj 1236 Network of Schools
poj.org/problem?id=1236 [题意] 给定一个有向图,求: (1)至少要选几个顶点,才能做到从这些顶点出发,可以到达全部顶点 (2)至少要加多少条边,才能使得从任何一个顶点出发,都 ...
- POJ 1236 Network Of Schools (强连通分量缩点求出度为0的和入度为0的分量个数)
Network of Schools A number of schools are connected to a computer network. Agreements have been dev ...
- poj 2762 强连通缩点+拓扑排序
这题搞了好久,先是拓扑排序这里没想到,一开始自己傻乎乎的跑去找每层出度为1的点,然后才想到能用拓扑排序来弄. 拓扑排序的时候也弄了挺久的,拓扑排序用的也不多. 题意:给一个图求是否从对于任意两个点能从 ...
- POJ 2762Going from u to v or from v to u?(强联通 + 缩点 + 拓扑排序)
[题意]: 有N个房间,M条有向边,问能否毫无顾虑的随机选两个点x, y,使从①x到达y,或者,②从y到达x,一定至少有一条成立.注意是或者,不是且. [思路]: 先考虑,x->y或者y-> ...
- Going from u to v or from v to u?_POJ2762强连通+并查集缩点+拓扑排序
Going from u to v or from v to u? Time Limit: 2000MS Memory Limit: 65536K Description I ...
随机推荐
- svn url does not contain valid patch
想把项目上传到svn上,由于误点击了apply patch.所以出现下面的错误. 正确做法是在项目上右击找到Team----share Project 如图: 点击share project后出现如图 ...
- bzoj2489
这种题完全可以暴力找规律,暴力打表各种搞法 这里有一篇比较全面的题解:http://acm.uestc.edu.cn/bbs/read.php?tid=3698&page=1&tore ...
- python - 简述list. extend() 和 append() 区别
>>> a = 'hello' >>> b = [1, 2, 3] >>> b.append(a) >>> b [1, 2, 3 ...
- Java [Leetcode 125]Valid Palindrome
题目描述: Given a string, determine if it is a palindrome, considering only alphanumeric characters and ...
- FFMPEG视音频编解码零基础学习方法
在CSDN上的这一段日子,接触到了很多同行业的人,尤其是使用FFMPEG进行视音频编解码的人,有的已经是有多年经验的“大神”,有的是刚开始学习的初学者.在和大家探讨的过程中,我忽然发现了一个问题:在“ ...
- linux笔试
在对linux基本知识的归纳总结之后,这里是一份linux的测试题.希望能帮助大家复习和熟悉linux知识. 一.选择题 1.cron 后台常驻程序 (daemon) 用于: A. 负责文件在网络中 ...
- HTML5之video元素
一.video元素支持的视频格式 HTML5中的video标签支持3种常用的视频格式: 1.Ogg = 带有Theora 视频编码和Vorbis 音频编码的 Ogg 文件: 2.MPEG4 = 带有H ...
- css3属性及事例
在看网上别的前端大牛的作品时,总会有新的收获,我想很多人应该都知道box-shadow,但是不知道有没有接触过这个 box-shadow: 2px 2px 4px rgba(0,0,0,0.4) , ...
- UITextField限制字数的方法
转:http://blog.csdn.net/marujunyy/article/details/9985411 在输入东西的时候,如果想限制最大字数,可以用下面方法: - (BOOL)textFie ...
- Oracle存储过程实现返回多个结果集 在构造函数方法中使用 dataset
原文 Oracle存储过程实现返回多个结果集 在构造函数方法中使用 dataset DataSet相当你用的数据库: DataTable相当于你的表.一个 DataSet 可以包含多个 DataTab ...