A

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 }
View Code
转载请备注:
**************************************
* 作者: Wurq
* 博客: https://www.cnblogs.com/Wurq/
* Gitee: https://gitee.com/wurq
**************************************
原文地址:https://www.cnblogs.com/Wurq/p/4692216.html