http://acm.hdu.edu.cn/showproblem.php?pid=1285
4 3 1 2 2 3 4 3
1 2 4 3
(1)从有向图中选择一个没有前驱(即入度为零)的顶点并且输出它。
(2)从网中删除该顶点,并且删除从该顶点发出的全部有向边。
(3)重复上述两步,直到剩余的网中不再存在没有前驱的顶点为止。
对于上面的算法,如果最终存在不能剩余的点,则剩余的点和期间的边一定构成环路,否则的话,算法结束时,图G的点都会别删除并输出。
利用邻接矩阵的实现:
#include <string.h> #include <stdio.h> #include <iostream> #define N 550 #define M 2100 using namespace std; int map[N][N],in[M],f[M]; int main() { int i,j,t,m,n,a,b,num; while(~scanf("%d %d",&n,&m)) { memset(map,0,sizeof(map)); memset(in,0,sizeof(in)); while(m--) { scanf("%d %d",&a,&b); if(map[a][b]==0) { map[a][b]=1; in[b]++; } } num=0; while(num!=n) { for(i=1;i<=n;i++) if(in[i]==0) { in[i]=-1; f[num++]=i; t=i; break; } for(j=1;j<=n;j++) { if(map[t][j]==1) { in[j]--; } } } for(i=0;i<n;i++) printf(i==n-1?"%d\n":"%d ",f[i]); } return 0; }
#include <string.h> #include <stdio.h> #include <iostream> using namespace std; int head[10005],ip,indegree[10005],queue[10005]; struct note { int to; int next; }; note edge[10005]; void add(int u,int v) { edge[ip].to=v,edge[ip].next=head[u],head[u]=ip++; } int main() { int m,n,a,b; while(~scanf("%d%d",&n,&m)) { memset(head,-1,sizeof(head)); memset(indegree,0,sizeof(indegree)); ip=0; for(int i=0; i<m; i++) { cin >> a >>b; add(a,b); indegree[b]++; } int c=0; while(c<n) { for(int i=1; i<=n; i++) { if(0==indegree[i]) { queue[c++]=i; indegree[i]=-1; for(int j=head[i]; j!=-1; j=edge[j].next) indegree[edge[j].to]--; break; } } } for(int i=0; i<c; i++) printf(i==c-1?"%d\n":"%d ",queue[i]); } return 0; }