题目链接:http://fastvj.rainng.com/problem/Gym-101480K
题目链接:
实际上我们只能确定出三种情况:
1.入度为0的点肯定在s集合内
2.s集合内挑战的点肯定在集合外
3.没有被s集合内挑战过的点肯定在s集合内
那么剩下的点肯定就是无法判断在s内还是外了,所以任取一边就好了,并且上面的三种情况我们可以用dfs处理。
剩下不确定的点肯定挑战的是对面不确定的或者是确定集合s外的点
#include<math.h>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
typedef long long ll;
const int mx = 2e5 + 10;
int n,top,vis[mx];
int a[mx],in[mx];
void dfs(int u,int d)
{
if(~vis[u]) return ;
vis[u] = d;
if(!d) dfs(a[u],1);
if(d) in[a[u]]--;
if(d&&!in[a[u]]) dfs(a[u],0);
}
int main()
{
scanf("%d",&n);
int v;
memset(vis,-1,sizeof(vis));
for(int i=1;i<=n;i++){
scanf("%d",&v);
a[i] = v,in[v]++;
}
for(int i=1;i<=n;i++){
scanf("%d",&v);
a[i+n] = v,in[v]++;
}
for(int i=1;i<=2*n;i++){
if(vis[i]==-1&&!in[i])
dfs(i,0);
}
for(int i=1;i<=2*n;i++){
if(!vis[i]||(vis[i]==-1&&i<=n))
printf("%d ",i);
}
puts("");
return 0;
}