Time Limit: 1000MS Memory Limit: 32768KB 64bit IO Format: %I64d & %I64u

Status

Description

为了训练小希的方向感,Gardon建立了一座大城堡,里面有N个房间(N<=10000)和M条通道(M<=100000),每个通道都是单向的,就是说若称某通道连通了A房间和B房间,只说明可以通过这个通道由A房间到达B房间,但并不说明通过它可以由B房间到达A房间。Gardon需要请你写个程序确认一下是否任意两个房间都是相互连通的,即:对于任意的i和j,至少存在一条路径可以从房间i到房间j,也存在一条路径可以从房间j到房间i。

Input

输入包含多组数据,输入的第一行有两个数:N和M,接下来的M行每行有两个数a和b,表示了一条通道可以从A房间来到B房间。文件最后以两个0结束。

Output

对于输入的每组数据,如果任意两个房间都是相互连接的,输出”Yes”,否则输出”No”。

Sample Input

3 3
1 2
2 3
3 1
3 3
1 2
2 3
3 2
0 0

Sample Output

Yes
No

Source


Tarjan求强连通分量并判断个数是否为1,即判断所给图是否为强连通图。注意n=1, m=0是成立的,判断输入结束那里WA了一发。。。
AC代码:
#include <iostream>
#include <cstring>
#include <stack>
#include <algorithm>
using namespace std;
int n, m;
const int maxn = 10010, maxm = 100010;
struct node
{
	int v, next;
}e[maxm];
int k, head[maxm];
void adde(int u, int v)
{
	e[k].v = v;
	e[k].next = head[u];
	head[u] = k++;
}
void input()
{
	k = 1;
	memset(head, -1, sizeof(head));
	for (int i = 0; i < m; i++)
	{
		int a, b;
		cin >> a >> b;
		adde(a, b);
	}
}
int dfn[maxn], low[maxn], belong[maxn];
int cnt, idx;
bool ins[maxn];
stack <int> s;
void tarjan(int u)
{
	int v;
	low[u] = dfn[u] = ++idx;
	s.push(u);
	ins[u] = 1;
	for (int i = head[u]; i != -1; i = e[i].next)
	{
		v = e[i].v;
		if (!dfn[v])
		{
			tarjan(v);
			low[u] = min(low[u], low[v]);
		}
		else if (ins[v])
			low[u] = min(low[u], dfn[v]);
	}
	if (low[u] == dfn[u])
	{
		cnt++;
		while (u != v)
		{
			v = s.top();
			s.pop();
			ins[v] = 0;
			belong[v] = cnt;
		}
	}
}
void solve()
{
	memset(dfn, 0, sizeof(dfn));
	memset(ins, 0, sizeof(ins));
	cnt = idx = 0;
	for (int i = 1; i <= n; i++)
		if (!dfn[i])
			tarjan(i);
	if (cnt == 1)
		cout << "Yes\n";
	else
		cout << "No\n";
}
int main()
{
	while (cin >> n >> m && (n || m))
	{
		input();
		solve();
	}
	return 0;
}

 

分类: ACM/ICPC

1 条评论

oneBite · 2017年3月5日 下午7:53

哥哥啊 能不能在贴出来的代码里稍微加点注释啊。。。

发表评论

电子邮件地址不会被公开。 必填项已用*标注