题意:给定一棵无根树,每次选编号最小的叶子删除,并将与该叶子相连的结点编号输出来。PS:无根树叶子的定义:度为1的点。

题解:按照拓扑排序方法,每次选择度为1且编号最小的点,将与它相连的点输出来,并将其度减一。

View Code
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cctype>
 5 using namespace std;
 6 int head[100],nc;
 7 struct Edge
 8 {
 9     int to,next;
10 } edge[10000];
11 void add(int a,int b)
12 {
13     edge[nc].to=b;
14     edge[nc].next=head[a];
15     head[a]=nc++;
16     edge[nc].to=a;
17     edge[nc].next=head[b];
18     head[b]=nc++;
19 }
20 int main()
21 {
22     char s[1000];
23     while(gets(s))
24     {
25         int cnt=0,dep[100],d[100],n=0;
26         memset(head,-1,sizeof(head));
27         memset(d,0,sizeof(d));
28         nc=0;
29         for(int i=0; s[i]!='\0'; i++)
30         {
31             if(s[i]=='(')
32                 cnt++;
33             else if(s[i]==')')
34                 cnt--;
35             else if(isdigit(s[i]))
36             {
37                 int sum=0;
38                 while(isdigit(s[i]))
39                 {
40                     sum=sum*10+s[i]-'0';
41                     i++;
42                 }
43                 i--;
44                 if(cnt!=1)
45                 {
46                     add(dep[cnt-1],sum);
47                     d[dep[cnt-1]]++;
48                     d[sum]++;
49                 }
50                 dep[cnt]=sum;
51                 n++;
52             }
53         }
54         if(n==1)
55         {
56             printf("\n");
57             continue;
58         }
59         for(int i=1; i<n-1; i++)
60         {
61             int id=1;
62             while(d[id]!=1)id++;
63             d[id]--;
64             for(int j=head[id]; j!=-1; j=edge[j].next)
65             {
66                 if(d[edge[j].to])
67                 {
68                     printf("%d ",edge[j].to);
69                     d[edge[j].to]--;
70                     break;
71                 }
72             }
73         }
74         printf("%d\n",n);
75     }
76     return 0;
77 }