URAL1022(拓扑排序)
解题思路:题目全英的,理解起来有点困难。刚开始我推测着应该是有向图中找一条包含所有顶点的通路,结果还是不对。如果早知道是拓扑排序就好办了。这是数据结构中的经典算法,首先找到入度为0的点,输出并去掉该顶点与其他顶点相连的边,然后依次循环上述操作,直到所有顶点都输出。需要定义一个存放顶点入度的数组(degree),最多100个顶点,所有可以用邻接矩阵存储有向图的结构,如果顶点过多,则应采用邻接表作有向图的存储结构。虽然题目中有不存在的情况,可是根据推断得知必定存在这样的序列。由程序提交结果验证确实如此。不过考虑到该情况也不会出错,就是麻烦些。
View Code
1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 using namespace std;
5 int map[105][105];
6 int degree[105],visit[105];
7 int main()
8 {
9 int i,j,n,x,y,k;
10 while(scanf("%d",&n)!=EOF)
11 {
12 memset(degree,0,sizeof(degree));
13 memset(map,0,sizeof(map));
14 memset(visit,0,sizeof(visit));
15 for(i=1;i<=n;i++)
16 {
17 scanf("%d",&x);
18 while(x!=0)
19 {
20 map[i][x]=1;
21 degree[x]++;
22 scanf("%d",&x);
23 }
24 }
25 for(i=1;i<=n;i++)
26 if(degree[i]==0&&!visit[i]){
27 visit[i]=1;
28 printf("%d",i);
29 break;
30 }
31 for(j=1;j<=n;j++)
32 if(map[i][j])degree[j]--;
33 k=1;
34 while(k<n)
35 {
36 for(i=1;i<=n;i++)
37 if(degree[i]==0&&!visit[i]){
38 visit[i]=1;
39 printf(" %d",i);
40 k++;
41 break;
42 }
43 for(j=1;j<=n;j++)
44 if(map[i][j])degree[j]--;
45 }
46 printf("\n");
47 }
48 return 0;
49 }
2 #include <cstdio>
3 #include <cstring>
4 using namespace std;
5 int map[105][105];
6 int degree[105],visit[105];
7 int main()
8 {
9 int i,j,n,x,y,k;
10 while(scanf("%d",&n)!=EOF)
11 {
12 memset(degree,0,sizeof(degree));
13 memset(map,0,sizeof(map));
14 memset(visit,0,sizeof(visit));
15 for(i=1;i<=n;i++)
16 {
17 scanf("%d",&x);
18 while(x!=0)
19 {
20 map[i][x]=1;
21 degree[x]++;
22 scanf("%d",&x);
23 }
24 }
25 for(i=1;i<=n;i++)
26 if(degree[i]==0&&!visit[i]){
27 visit[i]=1;
28 printf("%d",i);
29 break;
30 }
31 for(j=1;j<=n;j++)
32 if(map[i][j])degree[j]--;
33 k=1;
34 while(k<n)
35 {
36 for(i=1;i<=n;i++)
37 if(degree[i]==0&&!visit[i]){
38 visit[i]=1;
39 printf(" %d",i);
40 k++;
41 break;
42 }
43 for(j=1;j<=n;j++)
44 if(map[i][j])degree[j]--;
45 }
46 printf("\n");
47 }
48 return 0;
49 }