POJ 2762判断单联通(强连通缩点+拓扑排序)


Going from u to v or from v to u?

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 14789   Accepted: 3915

Description

In order to make their sons brave, Jiajia and Wind take them to a big cave. The cave has n rooms, and one-way corridors connecting some rooms. Each time, Wind choose two rooms x and y, and ask one of their little sons go from one to the other. The son can either
go from x to y, or from y to x. Wind promised that her tasks are all possible, but she actually doesn‘t know how to decide if a task is possible. To make her life easier, Jiajia decided to choose a cave in which every pair of rooms is a possible task. Given
a cave, can you tell Jiajia whether Wind can randomly choose two rooms without worrying about anything?

Input

The first line contains a single integer T, the number of test cases. And followed T cases.

The first line for each case contains two integers n, m(0 < n < 1001,m < 6000), the number of rooms and corridors in the cave. The next m lines each contains two integers u and v, indicating that there is a corridor connecting room u and room v directly.

Output

The output should contain T lines. Write ‘Yes‘ if the cave has the property stated above, or ‘No‘ otherwise.

Sample Input

1
3 3
1 2
2 3
3 1

Sample Output

Yes

Source

POJ Monthly--2006.02.26,zgl & twb

[Submit]   [Go Back]   [Status]  
[Discuss]

题意:对于任意两个节点u,v,如果能从u到v或者v到u,那么输出Yes,否则输出No。

思路:先强连通缩点,此时一定不含环,看能不能找到一条最长路包含所有的缩点就行(实际上是找判断单链),用拓扑排序就ok,不过如果只有一个强连通分量那么一定是Yes啦,否则topo排序判断 ,代码如下:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn =1e4+10;
const ll mod=20140413;
vector<int>G1[maxn],G2[maxn],G[maxn];
int sccno[maxn],vis[maxn],scc_cnt;//sccno强连通编号,scc_cnt表示强连通分量的个数
int ind[maxn];//ind表示入度
void init_G(int n)//初始化缩点图
{
	memset(ind,0,sizeof ind);
	for(int i=1;i<=n;i++)G[sccno[i]].clear();
	for(int i=1;i<=n;i++) {
		for(int j=0;j<G1[i].size();++j){
			int &v =G1[i][j];
			if(sccno[i]!=sccno[v]) {
				G[sccno[i]].push_back(sccno[v]);
				ind[sccno[v]]++;
			}
		}
	}
}
bool toposort(int n)//topo排序
{
	init_G(n);
	int u,cnt=0;
	queue<int>q;
	for(int i=1;i<=n;i++){
		if(!ind[sccno[i]]){
			if(!q.empty())return false;
			q.push(sccno[i]);
			cnt++;
		}
	}
	while(!q.empty()){
		u=q.front();
		q.pop();
		ind[u]=-1;
		for(int i=0;i<G[u].size();i++) {
			int &v=G[u][i];
			ind[v]--;
			if(ind[v]==0){
				if(!q.empty())return false;
				q.push(v);
				cnt++;
			}
		}
	}
	return cnt==scc_cnt;
}
vector<int>S;
void init(int n)
{
	memset(vis,0,sizeof vis);
	memset(sccno,0,sizeof sccno);
	S.clear();
	scc_cnt=0;
	for(int i=1;i<=n;i++) {
		G1[i].clear();
		G2[i].clear();
		G[i].clear();
	}
}
void AddEdge(int u,int v)
{
	G1[u].push_back(v);
	G2[v].push_back(u);
}
void dfs1(int u)
{
	if(vis[u])return ;
	vis[u]=1;
	for(int i=0;i<G1[u].size();i++)dfs1(G1[u][i]);
	S.push_back(u);
}
void dfs2(int u)
{
	if(sccno[u]) return ;
	sccno[u]=scc_cnt;
	for(int i=0;i<G2[u].size();++i)dfs2(G2[u][i]);
}
bool is_Semiconnect(int n)///计算强连通分量,初步判断
{
	for(int i=1;i<=n;i++)dfs1(i);
	for(int i=S.size();i>=1;i--){
		if(!sccno[S[i-1]]){
			scc_cnt++;
			dfs2(S[i-1]);
		}
	}
	return scc_cnt<=1;
}
int main()
{
   int T,n,m;
   scanf("%d",&T);
   while(T--) {
   		scanf("%d%d",&n,&m);
   		int u,v;
   		init(n);
   		while(m--) {
   			scanf("%d%d",&u,&v);
   			AddEdge(u,v);
   		}
   		if(is_Semiconnect(n))puts("Yes");
   		else{
   			if(toposort(n))puts("Yes");
   			else puts("No");
   		}
   	}
   return 0;
}
时间: 2024-11-08 20:08:35

POJ 2762判断单联通(强连通缩点+拓扑排序)的相关文章

POJ2762 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: 15196   Accepted: 4013 Description In order to make their sons brave, Jiajia and Wind take them to a big cave. The cave has n rooms, and one-way corridors

POJ 3114 - Countries in War(强连通分量+缩点+拓扑排序+DAG最短路)

Countries in War Time Limit:1000MS    Memory Limit:65536KB    64bit IO Format:%I64d & %I64u Appoint description: Description In the year 2050, after different attempts of the UN to maintain peace in the world, the third world war broke out. The impor

强连通分量与拓扑排序略解

$ ??????????????? ? $强连通分量与拓扑排序 拓扑排序 $ ??????$对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前.通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列.简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序. (by 百度百科) $

POJ 2762推断单个联通(支撑点甚至通缩+拓扑排序)

Going from u to v or from v to u? Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 14789   Accepted: 3915 Description In order to make their sons brave, Jiajia and Wind take them to a big cave. The cave has n rooms, and one-way corridors

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   Accepted: 4194 Description In order to make their sons brave, Jiajia and Wind take them to a big cave. The cave has n rooms, and one-way corridors

Poj 2186 Popular Cows(Tarjan 强连通缩点)

传送门:Poj 2186 题意:给你n头牛,m种关系,A牛认为B牛是popular的,B牛认为C牛是popular的,则A也认为C是popular的,问最终有几头被所有牛认为是popular的牛 题解:强连通缩点基础题(虽然我Tarjan和缩点都是对的,但是最终讨论判断的时候写垮了(写了3天....还不是你懒!!!!过年划水这么多天缩点后找出度为零的点个数.然后讨论是否有这样子的点,如果没有则全都是(整个都是强连通图),如果只有一个,那么那个强连通分量所含的牛的个数就是所求解,如果有多个那么都是

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条有向边,问该图中任意两点x, y之间是否满足x可以到y或者y可以到x. 一开始WA的原因是因为没注意到是或者, 如果是并且的话,就是一道简单的强连通分量的题,直接判断整个图是否为一个强连通分量 对于该题, 先用强连通分量进行缩点,简化图.图就变成了DAG,用拓扑排序判断图中点的入度, 图中入度为0

[模板]tarjan缩点+拓扑排序

题目:给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次. 题目简述:先tarjan缩点,再从入度为零处进行一次拓扑排序,求最长路即可,话说拓扑排序求最长路真方便... 注意: 要明确拓扑的写法,要用栈写最优. 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define man 100010 4 inline i

UVALive 6195 The Dueling Philosophers Problem 强连通缩点+拓扑序

题目链接:点击打开链接 给定n个点m条限制 下面限制 u->v 表示u必须排在v前面,问把n个数排成一排有多少种方法. 若有0种输出0 1种输出1 多种输出2 **边的数量题目里少了个0== 思路: 0种就是有环,缩点一下判断强连通分量是不是n个. 1种就是拓扑序时队列里任何时刻都只有一个点 否则就是2种 #pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h> #include