题目链接。
解题报告:
拓扑水题一道。
1.DFS检测是否有环。
#include <stdio.h> #include <string.h> #define MAXN 110 int G[MAXN][MAXN], v[MAXN]; int n, m; int dfs(int u){ v[u] = -1; int i; for(i=0; i<n; i++)if(G[u][i]){ if(v[i] < 0) return 0; if(!v[i] && !dfs(i)) return 0; } v[u] = 1; return 1; } int toposort(){ int i; for(i=0; i<n; i++)if(!v[i]){ if(!dfs(i)) return 0; } return 1; } int main(){ int i, a, b; while(scanf("%d %d", &n, &m) == 2 && n != 0){ memset(G, 0, sizeof(G)); memset(v, 0, sizeof(v)); for(i=0; i<m; i++){ scanf("%d %d", &a, &b); G[a][b] = 1; } if(toposort()) printf("YES\n"); else printf("NO\n"); } return 0; }
2. 或者不用DFS。。无前趋的顶点优先的拓扑排序方法 。寻找入度为0的点。。
#include <stdio.h> #include <string.h> #define MAXN 110 int G[MAXN][MAXN], indegree[MAXN]; int n, m; int toposort(){ int i, j, k; for(i=0; i<n; i++){ for(j=0; j<n; j++)if(indegree[j] == 0){ indegree[j]--; for(k=0; k<n; k++)if(G[j][k]) indegree[k]--; break; } if(j>=n) return 0; } return 1; } int main(){ int i, a, b; while(scanf("%d %d", &n, &m) == 2 && n != 0){ memset(G, 0, sizeof(G)); memset(indegree, 0, sizeof(indegree)); for(i=0; i<m; i++){ scanf("%d %d", &a, &b); if(G[a][b] == 0){ G[a][b] = 1; indegree[b]++; } } if(toposort()) printf("YES\n"); else printf("NO\n"); } return 0; }