题解 P6560 [SBCOI2020] 时光的流逝
首先考虑图上的点为 \(y\) 终点时,或者这个点无法继续向下走,即 \(du_i = 0\) 时,从这个点为起点先手必败,而对于每一个有一条指向先手必败的点的边的点,显然从这个点出发都是先手必胜的,以此类推。
可以考虑建反图,进行拓扑排序,转移状态。
#include<queue>
#include<cstdio>
using namespace std;
int cnt;
int du[100010],head[100010],f[100010],d[100010];
queue<int> q;
struct Node{
int to,nxt;
}edge[500010];
int read(){
int res=0;char c=getchar();
while(c>'9' || c<'0') c=getchar();
while(c>='0' && c<='9') res=res*10+c-'0',c=getchar();
return res;
}
int n=read(),m=read(),T=read();
int main(){
for(int i=1;i<=m;i++){
int x=read(),y;
edge[++cnt]=((Node){x,head[y=read()]}),
head[y]=cnt,du[x]++;
}
while(T--){
int s=read(),t=read();
for(int i=1;i<=n;i++){
f[i]=0,d[i]=du[i];
if(!d[i] || i==t) q.push(i),f[i]=-1;
}
while(q.size()){
int p=q.front();q.pop();
for(int i=head[p];i;i=edge[i].nxt)
if(!f[edge[i].to]){
if(f[p]==1){
if(!(--d[edge[i].to])) q.push(edge[i].to),f[edge[i].to]=-1;
}else q.push(edge[i].to),f[edge[i].to]=1;
}
}
printf("%d\n",f[s]);
}
return 0;
}
标签:int,题解,P6560,100010,SBCOI2020,流逝
From: https://www.cnblogs.com/Tyrue-blog/p/17802465.html