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的点只能存在一个, 若存在2个及以上的话,那么这2个点或多个点是无法互相到达。

在拓扑排序中用列队, 入度为0的点入队,每次都对列队中的数判断,若大于等于2则直接return 不满足。

#include<stdio.h>
#include<string.h>
#include<stack>
#include<queue>
#include<algorithm>
using namespace std;

int n, m, cnt, cnt1;
int head[1010], head1[1010];
int dfn[1010], low[1010], vis[1010], deep, k_color, color[1010];
stack<int>S;
int in[1010], flag;

struct Edge
{
	int to, next;
}edge[6010], edge1[6010];

void add(int a, int b)
{
	edge[++ cnt].to = b;
	edge[cnt].next = head[a];
	head[a] = cnt;
}

void add1(int a, int b)
{
	edge[++ cnt1].to = b;
	edge[cnt1].next = head1[a];
	head1[a] = cnt1;
}

void tarjan(int now)
{
	dfn[now] = low[now] = ++ deep;
	vis[now] = 1;
	S.push(now);
	for(int i = head[now]; i != -1; i = edge[i].next)
	{
		int to = edge[i].to;
		if(!dfn[to])
		{
			tarjan(to);
			low[now] = min(low[now], low[to]);
		}
		else if(vis[to])
		{
			low[now] = min(low[now], dfn[to]);
		}
	}
	if(dfn[now] == low[now])
	{
		k_color ++;
		while(1)
		{
			int temp = S.top();
			S.pop();
			color[temp] = k_color;
			vis[temp] = 0;
			if(temp == now)
				break;
		}
	}
}

void topo_sort()
{
	queue<int>Q;
	while(!Q.empty())
		Q.pop();
	for(int i = 1; i <= k_color; i ++)
		if(!in[i])
			Q.push(i);
	if(Q.size() > 1)
	{
		flag = 0;
		return ;
	}
	while(!Q.empty())
	{
		int temp = Q.front();
		Q.pop();
		for(int i = head1[temp]; i != -1; i = edge[i].next)
		{
			int to = edge[i].to;
			in[to] --;
			if(!in[to])
				Q.push(to);
			if(Q.size() > 1)
			{
				flag = 0;
				return ;
			}
		}
	}
}

int main()
{
	int T;
	scanf("%d", &T);
	while(T --)
	{
		flag = 1;
		cnt = deep = k_color = cnt1 = 0;
		memset(head, -1, sizeof(head));
		memset(in, 0, sizeof(in));
		memset(head1, -1, sizeof(head1));
		memset(dfn, 0, sizeof(dfn));
		memset(low, 0, sizeof(low));
		memset(vis, 0, sizeof(vis));
		scanf("%d%d", &n, &m);
		for(int i = 1; i <= m; i ++)
		{
			int a, b;
			scanf("%d%d", &a, &b);
			add(a, b);
		}
		for(int i = 1; i <= n; i ++)
			if(!dfn[i])
				tarjan(i);
		for(int i = 1; i <= n; i ++)//缩点
		{
			for(int j = head[i]; j != -1; j = edge[j].next)
			{
				int to = edge[j].to;
				int x = color[i], y = color[to];
				if(x != y)
				{
					add1(x, y);
					in[y] ++;
				}
			}
		}
		topo_sort();
		if(flag)
			printf("Yes\n");
		else
			printf("No\n");
	}
	return 0;
}

  

原文地址:https://www.cnblogs.com/yuanweidao/p/10757348.html

时间: 2024-11-04 13:28:46

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

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 2762 Going from u to v or from v to u?

Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 17689   Accepted: 4745 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,

POJ2762 Going from u to v or from v to u? 强连通+缩点

题目链接: poj2762 题意: 给出一幅单向图.问这张图是否满足   随意两点ab 都能 从a到达b 或  从b到达a 题解思路: 推断一幅图是否满足弱连通 首先想到的是将图中的 强连通分量(能互相到达的顶点集)  进行缩点 然后再依据原有边 又一次建图 假设缩点后的图是一条单链(回路,通路都能够)   则一定满足弱连通 推断是否是一条单链 能够依据建图过程中得到 入度 出度 数组进行推断 某点的入度 或 出度假设大于1则一定不是单链 另外单链仅仅能有一条  不能有多个点入度=0 代码: #

poj2762 Going from u to v or from v to u? --- 缩点+拓扑

给一个有向图,问是否该图上任意两点间可达. 首先容易想到缩点成有向无环图,其次就是如何处理任意两点间可达. 我在纸上画了一些情况: 4 3 1 2 2 3 2 4 4 4 1 2 1 3 2 4 3 4 3 3 1 2 2 3 1 3 7 8 1 2 1 3 3 4 2 4 4 5 4 6 5 7 6 7 5 6 1 2 1 3 2 3 3 4 3 5 4 5 NNYNY 根据这里一直在纠结如何通过入度出度直接判断.但是一直觉得不严谨.. 然后发现只要拓扑序列唯一即可.这样图中就没有 没有关系的

[poj2762] Going from u to v or from v to u?(Kosaraju缩点+拓排)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Going from u to v or from v to u? Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 14778   Accepted: 3911 Description In order to make their sons brave, Jiajia and Wind take them

【缩点+拓扑判链】POJ2762 Going from u to v or from v to u?

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 o

poj 2762 Going from u to v or from v to u? trajan+拓扑

Going from u to v or from v to u? 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 thei

POJ 2762 Going from u to v or from v to u?(强连通分量+拓扑排序)

职务地址:id=2762">POJ 2762 先缩小点.进而推断网络拓扑结构是否每个号码1(排序我是想不出来这点的. .. ).由于假如有一层为2的话,那么从此之后这两个岔路的点就不可能从一点到还有一点的. 代码例如以下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include