hdu1269
hdu1269
迷宫城堡
0x00 Tags
Tarjan算法
0x01 题目简介
实质:检测有向图是否为强连通图
0x02 代码
#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
int head[N], cnt, ans;
int dfn[N], low[N], index, vis[N];
int inf = 0x3f3f3f3f;
stack<int> s;
struct Edge
{
int to, next;
// 如果还有权值属性,也可以添加
}edge[N];
void Init()
{
//memset(head, -1, sizeof(head));
//memset(dfn, 0, sizeof(dfn));
//memset(low, 0, sizeof(low));
//memset(vis, 0, sizeof(vis));
for (int i = 0; i < N; i++)
{
head[i] = -1; // -1:不存在从结点i出发的边
edge[i].next = -1; // -1:结束,没有下一个边
dfn[i] = 0;
low[i] = 0;
vis[i] = 0;
}
cnt = 0;
}
void addedge(int u, int v)
{
edge[cnt].to = v;
edge[cnt].next = head[u]; // 指向结点u上一次存的边的位置
head[u] = cnt++; // 更新结点u最新边的存放位置:就是edge的末尾
}
void tarjan(int u)
{
dfn[u] = low[u] = index++; // 分配一个序号
vis[u] = 1; // 标记
s.push(u); // 进栈
for (int i = head[u]; ~i; i = edge[i].next) // 遍历v点出发的全部边
{
int v = edge[i].to; // u-->v的u点
if (dfn[v] == 0) // 如果这个点没访问过
{
tarjan(v); // 向下访问
low[u] = min(low[u], low[v]);
}
else if (vis[v])
{
low[u] = min(low[u], dfn[v]);
}
}
if (dfn[u] == low[u])
{
int nums = 0, j;
do {
j = s.top();
s.pop();
vis[j] = 0;
nums++;
} while (j != u);
ans = max(ans, nums);
}
}
int main()
{
int n, m;
while (scanf("%d%d", &n, &m) && (n + m))
{
Init();
cnt= 0, index = 1, ans = -inf;
for (int i = 0; i < m;i++)
{
int a, b;
scanf("%d%d", &a, &b);
addedge(a, b);
}
for (int i = 1; i <= n; i++)
{
if (!dfn[i]) tarjan(i);
}
if (ans == n) printf("Yes\n");
else printf("No\n");
}
return 0;
}