#include <bits/stdc++.h> # define LL long long using namespace std; struct Edge{ int to; int next; }e1[500010], e2[500010]; int head1[100010]; int head2[100010]; int en1,en2; int state[100010][2]; void add1(int from, int to){ e1[en1].next=head1[from]; e1[en1].to=to; head1[from]=en1; ++en1; } void add2(int from, int to){ //反向边 e2[en2].next=head2[from]; e2[en2].to=to; head2[from]=en2; ++en2; } int n,m,q; struct Sta{ int node; //走到哪儿个点 int ago; //轮到谁走 0代表A,1代表B int res; //结果是什么 0代表A赢,1代表B赢 }; int helper(int S, int T){ memset(state,-1,sizeof(state)); queue<Sta> q; for(int i=1;i<=n;i++){ if(head1[i]==-1){ //对于没有出度的点,轮到谁走谁输,终点同理 state[i][0]=1; //轮到A走,则B赢 state[i][1]=0; q.push({i,0,1}); q.push({i,1,0}); } } state[T][0]=1; state[T][1]=0; q.push({T,0,1}); q.push({T,1,0}); while(!q.empty()){ auto cur=q.front(); q.pop(); int curnode=cur.node; int who=cur.ago; int curres=cur.res; if(curres==1-who){ //若轮到A走,但是B赢,则前一个点若轮到B走,则B赢; 若轮到B走,但是A赢,则前一个点若轮到A走,则A赢 for(int i=head2[curnode];i!=-1;i=e2[i].next){ if(state[e2[i].to][1-who]!=-1) continue; state[e2[i].to][1-who]=curres; q.push({e2[i].to,1-who,curres}); } continue; } for(int i=head2[curnode];i!=-1;i=e2[i].next){ //对于每一个前面的点 int nextnode=e2[i].to; if(state[nextnode][1-who]!=-1) continue; int nextwho=1-who; bool flag=false; for(int j=head1[nextnode];j!=-1;j=e1[j].next){ //向后的点若都是轮到A走A赢,或者轮到B走B赢,则该点必输 if(state[e1[j].to][who]!=who){ flag=true; break; } } if(!flag){ state[nextnode][nextwho]=1-nextwho; q.push({nextnode,nextwho,1-nextwho}); } } } return state[S][0]; } int main(){ memset(head1,-1,sizeof(head1)); memset(head2,-1,sizeof(head2)); scanf("%d %d %d", &n, &m, &q); for(int i=0;i<m;i++){ int u,v; scanf("%d%d", &u, &v); add1(u,v); add2(v,u); } for(int i=0;i<q;i++){ int S,T; scanf("%d%d", &S, &T); int res=helper(S,T); if(res==1) printf("-1\n"); //在起点B赢 else if(res==0) printf("1\n"); //在起点A赢 else { printf("0\n"); } } return 0; }
T122085 [SBCOI2020]时光的流逝
猜你喜欢
转载自www.cnblogs.com/FEIIEF/p/12909361.html
今日推荐
周排行