# 圖論強連通專題：POJ2762

``````#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>

using namespace std;

const int maxn = 1000 + 10;
bool g[maxn][maxn];
vector<int> gg[maxn];
vector<int> G[maxn];
vector<int> rG[maxn];
vector<int> vs;
bool used[maxn];
int n,m;
int cmp[maxn];
bool vis[maxn];
int v_in[maxn];
queue<int> s;

void add_edge(int from, int to) {
G[from].push_back(to);
rG[to].push_back(from);
}

void dfs(int v) {
used[v] = true;
for (int i = 0; i < G[v].size(); i++) {
if (!used[G[v][i]]) dfs(G[v][i]);
}
vs.push_back(v);
}

void rdfs(int v, int k) {
used[v] = true;
cmp[v] = k;
for (int i = 0; i < rG[v].size(); i++) {
if (!used[rG[v][i]]) rdfs(rG[v][i],k);
}
}

int scc() {
memset(used,0,sizeof(used));
vs.clear();
for (int i = 1; i <= n; i++) {
if (!used[i]) dfs(i);
}
memset(used,0,sizeof(used));
int k = 0;
for (int i = vs.size() - 1; i >=0; i--) {
if (!used[vs[i]]) rdfs(vs[i],k++);
}
return k;
}

bool top_sort(int n) {
if (n == 1) return true;
bool f = true;
for (int i = 0; i < n; i++)
if (!v_in[i] && f) {
s.push(i);
f = false;
}
else if (!v_in[i]) return false;
while (!s.empty()) {
int u = s.front();s.pop();
f = true;
for (int i = 0; i < gg[u].size(); i++) {
v_in[gg[u][i]]--;
if (!v_in[gg[u][i]] && f) {
s.push(gg[u][i]);
f = false;
}
else if (!v_in[gg[u][i]]) return false;
}
}
return true;
}

int main() {
int t;
cin>>t;
while (t--) {
cin>>n>>m;
while (!s.empty()) s.pop();
for (int i = 0; i <= n; i++) {
G[i].clear();
rG[i].clear();
gg[i].clear();
}
for (int i = 0; i < m; i++) {
int a,b;
scanf("%d%d",&a,&b);
}
int nN = scc();
memset(g,0,sizeof(g));
memset(v_in,0,sizeof(v_in));
for (int i = 1; i <= n; i++) {
for (int j = 0; j < G[i].size(); j++) {
if (cmp[i] != cmp[G[i][j]] && !g[cmp[i]][cmp[G[i][j]]]) {
g[cmp[i]][cmp[G[i][j]]] = true;
v_in[cmp[G[i][j]]] ++;
gg[cmp[i]].push_back(cmp[G[i][j]]);
}
}
}
memset(vis,0,sizeof(vis));
if (top_sort(nN)) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
}
``````