HDU 3342 题目大意就是给定的有向图是否构成环,构成了则输出NO 否则 输出YES。 就是拓扑排序算法去做,不过还可以DFS去做。 拓扑排序的版本: #include <stdio.h> #include <string.h> #define maxn 105 int edge[maxn][maxn],flag,count[maxn]; /*=============*/ /*拓扑排序 INIT : edge[][]置为图的邻接矩阵;count[0..i..n-1];表示顶点i的入度 */ /*=============*/ void topoorder(int n) { int i,k,top=-1; for(i=0;i<n;i++)//将入度为0压栈 下标 模拟堆栈 { if(count[i]==0) {count[i] = top;top=i;} } for(i=0;i<n;i++) { if(top==-1){ //printf("存在回路"); flag=0; return;} else { int j=top;top=count[top];//退栈顶点元素给j //printf("%d/n",j);//输出排序后的顶点序列 //将j的所有直接后继的顶点的入度数减1 并且将入度减至0的顶点入栈 for(k=0;k<n;k++) { if(edge[j][k]&&(--count[k])==0) { count[k]=top;top=k; } } } } } int main(int argc, char *argv[]) { int n,m,i,j; int x,y; while(scanf("%d%d",&n,&m),n||m) { flag=1; memset(edge,0,sizeof(edge)); memset(count,0,sizeof(count)); for(i=0;i<m;i++) { scanf("%d%d",&x,&y); edge[x][y]=1; } //统计各个顶点的入度 for(i=0;i<n;i++) { for(j=0;j<n;j++) if(edge[i][j]){ count[j]++; } } topoorder( n); if(flag) { printf("YES/n"); } else printf("NO/n"); } return 0; } DFS版本: #include<stdio.h> #include<string.h> int p[105],ans[105][105]; int n,m,tt; void dfs(int t) { int i; if(p[t]) { tt=1; return ; } for(i=0;i<n;i++) { if(ans[t][i]&&!tt) { p[t]=1; dfs(i); p[t]=0; } } } int main() { int x,y,i,j; while(scanf("%d%d",&n,&m),n) { tt=0; for(i=0;i<105;i++) for(j=0;j<105;j++) ans[i][j]=0; memset(p,0,sizeof(p)); for(i=0;i<m;i++) { scanf("%d%d",&x,&y); ans[x][y]=1; } for(i=0;i<n;i++) { dfs(i); if(tt)break; } if(tt)printf("NO/n"); else printf("YES/n"); } return 0; }