题意:给定一棵无根树,每次选编号最小的叶子删除,并将与该叶子相连的结点编号输出来。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 }

浙公网安备 33010602011771号