采用Tarjan算法,判断图中是否有强连通分量
#include <bits/stdc++.h>
#define io cin.tie(0), cout.tie(0), ios::sync_with_stdio(false)
#define LL long long
#define ULL unsigned long long
#define EPS 1e-8
#define INF 0x7fffffff
#define SUB -INF - 1
using namespace std;
const int N = 100005;
int cnt;
int low[N], num[N], dfn;
int sccno[N], stack[N], top;
vector<int> G[N];
void dfs(int u)
{
stack[top++] = u;
low[u] = num[u] = ++dfn;
for (int i = 0; i < G[u].size(); i++)
{
int v = G[u][i];
if (!num[v])
{
dfs(v);
low[u] = min(low[u], low[v]);
}
else if (!sccno[v])
low[u] = min(low[u], num[v]);
}
if (low[u] == num[u])
{
cnt++;
while (1)
{
int v = stack[--top];
sccno[v] = cnt;
if (u == v)
break;
}
}
}
void Tarjan(int n)
{
cnt = top = dfn = 0;
memset(sccno, 0, sizeof(sccno));
memset(num, 0, sizeof(num));
memset(low, 0, sizeof(low));
for (int i = 1; i <= n; i++)
if (!num[i])
dfs(i);
}
int main()
{
int n, m, u, v;
while (scanf("%d%d", &n, &m), n != 0 || m != 0)
{
for (int i = 1; i <= n; i++)
G[i].clear();
for (int i = 0; i < m; i++)
{
scanf("%d%d", &u, &v);
G[u].push_back(v);
}
Tarjan(n);
printf("%s\n", cnt == 1 ? "Yes" : "No");
}
return 0;
}