思路
缩点之后 如果有大小为2的联通块肯定不符合题意
之后再进行 拓扑排序 如果拓扑序唯一 则符合 否则不符合
#include <bits/stdc++.h>
using namespace std;
#define int long long
//typedef long long ll;
typedef pair<int,int> pii;
#define x first
#define y second
#define pb push_back
#define inf 1e18
#define IOS std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fer(i,a,b) for(int i=a;i<=b;i++)
#define der(i,a,b) for(int i=a;i>=b;i--)
const int maxn=1e5+10;
const int mod=1e9+7;
int qmi(int a,int b) {
int res=1;
while(b) {
if(b&1) res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
const int N=2e5+10;
int dr[4][2]= {{-1,0},{1,0},{0,-1},{0,1}};
int n,k;
int m;
int low[N];
int dfn[N],ins[N],idx,cnt;
vector<int>g[N];
vector<int>e[N];
int bel[N];
int sz[N];
stack<int>s;
void dfs(int u) {
dfn[u] = low[u] = ++idx;
ins[u] = true;
stk.push(u);
for (auto v : e[u]) {
if (!dfn[v]) dfs(v);
if (ins[v]) low[u] = min(low[u], low[v]);
}
if (dfn[u] == low[u]) {
++cnt;
while (true) {
int v = s.top();
ins[v] = false;
bel[v] = cnt;
sz[cnt]++;
s.pop();
if (v == u) break;
}
}
}
int d[N];
bool to(){
queue<int>q;
fer(i,1,cnt){
if(!d[i])q.push(i);
}
int f=1;
while(!q.empty()){
int u=q.front();
if(q.size()>1)f=0;
q.pop();
for(auto v:e[u]){
if(!--d[v])q.push(v);
}
}
return f;
}
void solve() {
cin>>n>>m;
fer(i,1,m) {
int a,b;
cin>>a>>b;
g[a].push_back(b);
//g[b].push_back(a);
}
fer(i,1,n)if(!dfn[i])dfs(i);
fer(i,1,n) {
for(auto v:g[i]) {
if(bel[i]!=bel[v])e[bel[i]].push_back(bel[v]),d[bel[v]]++;
}
}
// cout<<cnt;
fer(i,1,cnt) {
cout<<sz[i];
if(sz[cnt]==2) {
cout<<"NO"<<endl;
return ;
}
}
if(to())cout<<"YES"<<endl;
else cout<<"NO"<<endl;
while(!s.empty())s.pop();
for(int i=1;i<=n;i++){
bel[i]=dfn[i]=low[i]=cnt=sz[i]=ins[i]=d[i]=idx=0;
g[i].clear();
e[i].clear();
}
}
signed main() {
IOS;
int _;
cin>>_;
while(_--) solve();
return 0;
}