codeforces 681D Gifts by the List dfs+构造

时间:2024-01-15 13:36:38

题意:给你一个森林,表示其祖先关系(自己也是自己的祖先),每个人有一个礼物(要送给这个人的固定的一个祖先)

让你构造一个序列,使得的对于每个人,这个序列中第一个出现的他的祖先,是他要送礼物的的那个祖先

分析:这个序列满足

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+;
const int INF=0x3f3f3f3f;
const int mod=1e9+;
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,-,sizeof(head));
for(int i=;i<m;++i){
int u,v;
scanf("%d%d",&u,&v);
++d[v];add(u,v);
}
for(int i=;i<=n;++i){
scanf("%d",&a[i]);
vis[a[i]]=true;
}
for(int i=;i<=n;++i)
if(!d[i])dfs(i,i);
for(int i=;i<=n;++i)
if(ret[i]!=a[i]){printf("-1\n");return ;}
printf("%d\n",s.size());
while(!s.empty()){
printf("%d\n",s.top());
s.pop();
}
return ;
}