BZOJ4436 [Cerc2015]Kernel Knights

来源:互联网 发布:x8线切割编程软件 编辑:程序博客网 时间:2024/05/08 23:53

一个点x如果不被任意S中的骑士挑战那么他一定在S中,如果S中存在一个骑士挑战了他那么他一定不在S中

所以找所有入度为0的点x,加入S,并把x连的所有点y的所有连出的点yy的入度减一,直到剩下的全是环,因为是二分图所以没有奇环,环上的点任意隔一个加到S里即可

#include<iostream>#include<cstdlib>#include<cstdio>#include<cstring>#include<cmath>#include<ctime>#include<algorithm>#include<iomanip>#include<vector>#include<stack>#include<queue>#include<map>#include<set>#include<bitset>using namespace std;#define MAXN 200010#define MAXM 1010#define ll long long#define INF 1000000000#define MOD 1000000007#define eps 1e-8struct vec{int to;int fro;};vec mp[MAXN];int tai[MAXN],cnt;int d[MAXN];int n;int q[MAXN],hd,tl;bool vis[MAXN];bool is[MAXN];inline void be(int x,int y){mp[++cnt].to=y;mp[cnt].fro=tai[x];tai[x]=cnt;}void get(int x,bool c){int i,y;vis[x]=1;is[x]=c;for(i=tai[x];i;i=mp[i].fro){y=mp[i].to;if(!vis[y]){get(y,c^1);}}}int main(){int i,j,x,y,yy;scanf("%d",&n);for(i=1;i<=n;i++){scanf("%d",&x);be(i,x);d[x]++;}for(i=1;i<=n;i++){scanf("%d",&x);be(n+i,x);d[x]++;}for(i=1;i<=n*2;i++){if(!d[i]){q[tl++]=i;vis[i]=1;}}while(hd!=tl){x=q[hd++];is[x]=1;for(i=tai[x];i;i=mp[i].fro){y=mp[i].to;if(vis[y]){continue ;}vis[y]=1;for(j=tai[y];j;j=mp[j].fro){yy=mp[j].to;d[yy]--;if(!d[yy]){q[tl++]=yy;vis[yy]=1;}}}}for(i=1;i<=n;i++){if(!vis[i]){get(i,1);}}for(i=1;i<=n*2;i++){if(is[i]){printf("%d ",i);}}return 0;}/**/


0 0
原创粉丝点击