题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=6026
拓扑排序判断环是否存在,DFS搜1~n大于/小于i的元素数量
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <map> #include <set> #include <vector> #include <string> #include <cstring> #include <queue> #define eps 1e-8 using namespace std; typedef long long ll; static const int MAX_N = 1e2 + 5; static const ll Mod = 233; static const int INF = 0x3f3f3f3f; vector<int>veh[MAX_N]; vector<int>vel[MAX_N]; int in[MAX_N], cnth[MAX_N], cntl[MAX_N]; bool vis[MAX_N]; int n; bool topolog(){ queue<int>q; for(int i = 1; i <= n; ++i) if(!in[i]) q.push(i); while(!q.empty()){ int now = q.front(); q.pop(); if(!vis[now]){ vis[now] = true; for(int i = 0; i < vel[now].size(); ++i){ int v = vel[now][i]; if(--in[v] == 0) q.push(v); } } } for(int i = 1; i <= n; ++i){ if(!vis[i]) return false; } return true; } void dfs(int u, int &rev, bool fg){ //这里dfs有待改进,传参vector更好,但不会... vis[u] = true; if(fg){ for(int i = 0; i < vel[u].size(); ++i){ int v = vel[u][i]; if(!vis[v]){ ++rev; vis[v] = true; dfs(v, rev, fg); } } } else{ for(int i = 0; i < veh[u].size(); ++i){ int v = veh[u][i]; if(!vis[v]){ ++rev; dfs(v, rev, fg); } } } } int main(){ // freopen("input.txt", "r", stdin); // freopen("output.txt", "w", stdout); int T; scanf("%d", &T); while(T--){ int m; scanf("%d%d", &n, &m); for(int i = 0; i <= n; ++i){ vel[i].clear(); veh[i].clear(); vis[i] = false; in[i] = 0; cnth[i] = 0; cntl[i] = 0; } for(int i = 0; i < m; ++i){ int u, v; scanf("%d%d", &u, &v); vel[u].push_back(v); veh[v].push_back(u); ++in[v]; } if(!topolog()) for(int i = 1; i <= n; ++i) putchar('0'); else{ bool fg = true; for(int i = 1; i <= n; ++i){ memset(vis, false, sizeof(vis)); int rev = 0; dfs(i, rev, fg); cntl[i] = rev; } fg = false; for(int i = 1; i <= n; ++i){ memset(vis, false, sizeof(vis)); int rev = 0; dfs(i, rev, fg); cnth[i] = rev; } int mv = (n - 1) >> 1; for(int i = 1; i <= n; ++i){ putchar(cntl[i] <= mv && cnth[i] <= mv ? '1' : '0'); } } putchar('\n'); } }