枚举每个点的入度-1,无须考虑删除的是哪一条边,然后拓扑排序。若每个点都能遍历到则YES,否则NO
#include"bits/stdc++.h"
using namespace std;
const int MAXN = 555;
int du[MAXN],ru[MAXN];
bool vis[MAXN];
vector <int> G[MAXN];
int n,m;
bool check(int x)
{
queue<int> que;
fill(vis+1,vis+1+n,0);
for(int j = 1; j <= n; j++)
du[j] = ru[j];
du[x]--;
for(int i = 1; i <= n; i++)
if(du[i] == 0){
que.push(i);
vis[i] = 1;
}
while(que.size()){
int u = que.front(); que.pop();
for(int i = 0; i < G[u].size(); i++){
int v = G[u][i];
du[v]--;
if(du[v] <= 0 && !vis[v]){
que.push(v);
vis[v] = 1;
}
}
}
bool flag = 1;
for(int i = 1; i <= n; i++)
if(!vis[i]) flag = 0;
return flag;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i = 1; i <= m; i++){
int u,v;
scanf("%d%d",&u,&v);
G[u].push_back(v);
ru[v]++;
}
bool flag = check(0);
if(!flag) for(int i = 1; i <= n; i++)
if(ru[i]){
flag = check(i);
if(flag) break;
}
if(flag) puts("YES");
else puts("NO");
return 0;
}