题意
大致题意:对于某个火星人来说,他可以有一个父母,也可以有多个父母(什么impart),求一个发言顺序,使得长辈总是先比晚辈发言。
思路
先构图,对于每一对长辈和晚辈,可以存一条边:长辈-->晚辈,我们发现,因为要使得长辈比晚辈先发言,对于当前该由谁发言,如果某个火星人是有被某个长辈指着的,说明不能由该名火星人发言,因为此时他发言就使得晚辈比长辈先发言,如果某个火星人是没有被某个长辈指着的,说明其可以发言。那对于该名火星人的子代,因为该名火星人已经发言完了,可以消除他的影响,就可以把由该名火星人指向他的子代的箭头擦除。到这里,我们就看出,这就是拓扑排序的过程。
代码
#include <iostream>
#include <queue>
using namespace std;
queue<int>topu;
int idx=1,head[105],e[10005],en[10005],d[105];
void add(int u,int v){
e[idx]=v;
en[idx]=head[u];
head[u]=idx++;
}
int main(){
int n;cin>>n;
for(int i=1;i<=n;i++){
while(1){
int temp;cin>>temp;
if(temp==0)break;
add(i,temp);
d[temp]++;
}
}
for(int i=1;i<=n;i++){
if(d[i]==0)topu.push(i);
}
while(!topu.empty()){
int temp=topu.front();
printf("%d ",temp);
topu.pop();
for(int i=head[temp];i;i=en[i]){
d[e[i]]--;
if(d[e[i]]==0)topu.push(e[i]);
}
}
}