A - 小Y上学记——修学分
Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others)
Problem Description
小Y终于如愿以偿地通过高考来到了魂牵梦萦的大学校园——ACdream大学。来到校园的第一件事就是选课。
由于每一门课都有1个学分~而且有一些课需要先学完别的课程(例如必须先学会高等数学,才能学会量子力学,必须先学会走,才能学会跑)
ACdream大学需要学生修够若干学分才允许毕业。
请按顺序输出小Y的一种方案(若不止一种答案,请输出字典序最小的一种方案)
Input
多组数据,每组数据首先是两个整数n,m,k,分别表示学科总数,学科之间的关系数,以及毕业所需的最少学分。
(2<=n<=100, 0<=m<=500,1<=k<=n)
接下来是m行,每行是两个整数a,b表示学科a是学科b的前置学科。
Output
对于每组数据,若小Y不存在任何方案选课,请输出-1.
否则在一行输出m个整数,表示小Y按顺序修的学科编号。
Sample Input
2 1 2 0 1 2 2 2 1 0 0 1 3 2 1 1 0 0 1 3 0 3
Sample Output
0 1 -1 2 0 1 2
Hint
对于第一组数据,先修完第0学科,获得1学分,再修以第0学科为前置学科的第1学科,获得1学分,即可满足毕业条件:2学分。
对于第二组数据,由于第0学科的前置学科为第1学科,而第1学科的前置学科为第2学科,因此小Y无论如何也无法满足毕业条件。
对于第三组数据,由于多了第2学科,而且第2学科不需要前置学科,因此只需要修完第2学科即可满足毕业条件了。
对于第四组数据,没有任何的先后限制,因此6种全排列方案均符合题意,字典序最小的方案为0,1,2
解法:ToPoSort一下,排序K个即可。
代码:2015.7.30
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <map> 5 #define MAX 505 6 using namespace std; 7 int InD[505];/*InD[i]记录点i的入度*/ 8 int First[MAX];/*First[i]头结点的第一条边的编号*/ 9 struct edge 10 { 11 int TO;/*点*/ 12 int Next;/*下一条边的编号*/ 13 }ID[3*MAX]; 14 int SIGN; 15 void Add_E(int x,int y)/*添加点操作*/ 16 { 17 ID[SIGN].TO=y; 18 InD[y]++; 19 ID[SIGN].Next=First[x]; 20 First[x]=SIGN++; 21 } 22 int Jude(int x,int y)/*查找与X是否与Y相连*/ 23 { 24 int i; 25 for(i=First[x];i!=0;i=ID[i].Next) //查找与该点相关的点 26 { 27 if(ID[i].TO==y)return 0; 28 } 29 return 1; 30 } 31 int ToPoSort(int N,int Num[],int K)/*拓扑排序,邻接表*/ 32 { 33 int i,j,k; 34 for(j=0;j<N;j++) 35 { 36 for(i=1;i<=N;i++) 37 { 38 if(InD[i]==0) 39 { 40 InD[i]--; 41 Num[j]=i; 42 for(k=First[i];k!=0;k=ID[k].Next) 43 { 44 InD[ID[k].TO]--; 45 } 46 break; 47 } 48 } 49 if(i>N)break; 50 } 51 if(j>=K)return 1; 52 else return 0; 53 } 54 int main() 55 { 56 int M,N,K,i; 57 int a,b; 58 int Num[MAX]; 59 while(scanf("%d%d%d",&N,&M,&K)!=EOF) 60 { 61 for(i=1;i<=N;i++){First[i]=0;InD[i]=0;} 62 for(i=0,SIGN=1;i<M;i++) 63 { 64 scanf("%d%d",&a,&b);a+=1;b+=1; 65 Add_E(a,b); 66 } 67 if(ToPoSort(N,Num,K))/*拓扑排序*/ 68 { 69 for(i=0;i<K;i++) 70 { 71 if(i!=0)putchar(32); 72 printf("%d",Num[i]-1); 73 }putchar(10); 74 } 75 else printf("-1 "); 76 } 77 return 0; 78 }