CodeForces 681D Gifts by the List

$dfs$,后续遍历。

如果某个节点$a[i]=i$,那么$i$的后继的$a[i]$都要指向$i$,直到出现新的后继$j$,$a[j]=j$。利用这个可以判断是否有解。

如果有解的话,那么只要输出后序遍历的结果就可以了。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0),eps=1e-6;
void File()
{
    freopen("D:\in.txt","r",stdin);
    freopen("D:\out.txt","w",stdout);
}
template <class T>
inline void read(T &x)
{
    char c = getchar(); x = 0;
    while(!isdigit(c)) c = getchar();
    while(isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); }
}

const int maxn=100010;
int m,n,k,a[maxn],r[maxn];
vector<int>g[maxn];
bool flag[maxn],fail,f[maxn];
vector<int>ans;

void dfs(int x,int y)
{
    if(a[x]==x) y=x;
    else  { if(a[x]!=y) fail=1; }
    for(int i=0;i<g[x].size();i++) dfs(g[x][i],y);
    if(f[x]) ans.push_back(x);
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        int u,v; scanf("%d%d",&u,&v);
        g[u].push_back(v); r[v]++;
    }
    for(int i=1;i<=n;i++) { scanf("%d",&a[i]); f[a[i]]=1; }
    for(int i=1;i<=n;i++) if(r[i]==0) dfs(i,i);
    if(fail) printf("-1
");
    else
    {
        printf("%d
",ans.size());
        for(int i=0;i<ans.size();i++) printf("%d
",ans[i]);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/zufezzt/p/5860463.html