题意:有n个学生,比了一场比赛,但是榜单看不到了。现在告诉你m段信息,每段信息的内容是(a,b),表示a的排名比b的高。问你能不能根据这些信息得出这场比赛的前k名。
思路:用拓扑排序找出一组符合k个人的解,然后判断这组解是否唯一,如果这组解是唯一的,那么剩下的n-k个人一定都在这k个人后面。dfs一下就行了。
代码:
1 #include<stdio.h> 2 #include<string.h> 3 const int N=1111,M=11111; 4 struct node 5 { 6 int v,next; 7 }e[M]; 8 int head[N],cnt,d[N],mark[N],p[N],js,tmp[N]; 9 void add(int u,int v) 10 { 11 e[cnt].v=v,e[cnt].next=head[u]; 12 head[u]=cnt++; 13 } 14 void dfs(int u) 15 { 16 if(!p[u]&&!mark[u]) js++; 17 p[u]=1; 18 for(int i=head[u];i!=-1;i=e[i].next) 19 { 20 if(!p[e[i].v]) 21 dfs(e[i].v); 22 } 23 } 24 int main() 25 { 26 int n,m,k,i,u,v,f,j; 27 while(scanf("%d%d%d",&n,&k,&m)!=EOF) 28 { 29 memset(head,-1,sizeof(head)); 30 memset(d,0,sizeof(d)); 31 memset(mark,0,sizeof(mark)); 32 js=cnt=0; 33 while(m--) 34 { 35 scanf("%d%d",&u,&v); 36 add(u,v); 37 d[v]++; 38 } 39 while(js<k) 40 { 41 for(i=1;i<=n&&d[i];i++); 42 tmp[++js]=i;mark[i]=1; 43 d[i]--; 44 for(i=head[i];i!=-1;i=e[i].next) 45 d[e[i].v]--; 46 } 47 for(i=1;i<=k;i++) 48 { 49 memset(p,0,sizeof(p)); 50 js=0; 51 dfs(tmp[i]); 52 if(js!=n-k) break; 53 } 54 if(i>k) printf("YES\n"); 55 else printf("NO\n"); 56 } 57 return 0; 58 }
参考文章:http://www.cnblogs.com/algorithms/archive/2012/07/02/2573631.html