luogu P5663 加工零件
题面传送门
看看像个图论,实际就是图论。仔细推几个样例就可以发现,这与奇偶数有关。而题目中又明显强调
\(1∼n\) 编号。某些工人之间存在双向的零件传送带。保证每两名工人之间最多只存在一条传送带。
于是我们可以用\(spfa\)求出点\(1\)到其他点的奇偶最短路,然后当\(x_i\)想生产\(y_i\)时,首先判断\(y_i\)的奇偶性然后将\(y_i\)与他同奇偶的\(dist_{x_{i}}\)比较,如果\(y_i\)<\(dist_{x_{i}}\),那么就\(Game Over\)了,\(else\) 那么就一定要生产。
//题外话:这道题读入输出特别大,所以建议用快读快输
代码:
#include<cstdio>
#include<queue>
#include<vector>
#include<cstring>
using namespace std;
int n,m,k,x,y,dj[393939],du[393939],cur,flag;
vector<int> f[393939];
struct yy{
int to,w;
}now;
queue<yy> q;
void read(int &x){
x=0;register int f=1;register char s=getchar();
while(s<'0'||s>'9') s=getchar();
while(s>='0'&&s<='9') x=(x<<3)+(x<<1)+s-'0',s=getchar();
}
int main(){
// freopen("work.in","r",stdin);
// freopen("work.out","w",stdout);
register int i,j,k,longge,cur;
register yy now;
read(n);read(m); read(k);
for(i=1;i<=m;i++){
read(x);read(y);
f[x].push_back(y);
f[y].push_back(x);
}
memset(dj,0x3f,sizeof(dj));
memset(du,0x3f,sizeof(du));
du[1]=0;
q.push((yy){1,0});
while(!q.empty()){
now=q.front();longge=f[now.to].size();
q.pop();
for(i=0;i<longge;i++){
cur=f[now.to][i];
if(!now.w&&dj[cur]>du[now.to]+1)dj[cur]=du[now.to]+1,q.push((yy){cur,1});
if(now.w&&du[cur]>dj[now.to]+1)du[cur]=dj[now.to]+1,q.push((yy){cur,0});
}
}
for(i=1;i<=k;i++){
read(x);read(y);
if((!(y&1))){
if(x==1){
if(!f[1].size()) putchar('N'),putchar('o'),putchar('\n');
else putchar('Y'),putchar('e'),putchar('s'),putchar('\n');
continue;
}
if(du[x]<=y) putchar('Y'),putchar('e'),putchar('s'),putchar('\n');
else putchar('N'),putchar('o'),putchar('\n');
}
else{
if(dj[x]<=y) putchar('Y'),putchar('e'),putchar('s'),putchar('\n');
else putchar('N'),putchar('o'),putchar('\n');
}
}
return 0;
}