题意:给你一个森林,表示其祖先关系(自己也是自己的祖先),每个人有一个礼物(要送给这个人的固定的一个祖先)
让你构造一个序列,使得的对于每个人,这个序列中第一个出现的他的祖先,是他要送礼物的的那个祖先
分析:这个序列满足
1:我们这个序列只需要出现那些被送礼物的人就好了
2:这个序列的元素保证,如果x是y的祖先,那么x在y的后面
具体:这个序列可以通过dfs构造,然后最后check一下这个序列
注:check的过程和构造序列的dfs过程同步
#include <cstdio> #include <iostream> #include <ctime> #include <vector> #include <cmath> #include <map> #include <stack> #include <queue> #include <algorithm> #include <cstring> using namespace std; typedef long long LL; const int N=1e5+5; const int INF=0x3f3f3f3f; const int mod=1e9+7; struct Edge{ int v,next; }edge[N]; int head[N],tot,d[N],n,m,a[N],ret[N]; void add(int u,int v){ edge[tot].v=v; edge[tot].next=head[u]; head[u]=tot++; } stack<int>s; bool vis[N]; void dfs(int u,int fir){ if(vis[u])fir=u,s.push(u); ret[u]=fir; for(int i=head[u];~i;i=edge[i].next) dfs(edge[i].v,fir); } int main(){ scanf("%d%d",&n,&m); memset(head,-1,sizeof(head)); for(int i=0;i<m;++i){ int u,v; scanf("%d%d",&u,&v); ++d[v];add(u,v); } for(int i=1;i<=n;++i){ scanf("%d",&a[i]); vis[a[i]]=true; } for(int i=1;i<=n;++i) if(!d[i])dfs(i,i); for(int i=1;i<=n;++i) if(ret[i]!=a[i]){printf("-1 ");return 0;} printf("%d ",s.size()); while(!s.empty()){ printf("%d ",s.top()); s.pop(); } return 0; }