
题目概述题目传送门工厂里有n名工人工人之间有双向传送带连接生产规则如下如果x号工人想生产一个被加工到第 L(L1) 阶段零件则所有与 x 号工人有传送带直接相连的工人都需要生产第L-1阶段零件。如果x号工人想生产一个被加工到第 1 阶段的零件则所有与 x 号工人有传送带直接相连的工人都需要为x号工人提供一个原材料。轩轩是 1 号工人。现在给出 q 张工单第 i 张工单表示编号为 ai的工人想生产一个第Li阶段的零件。轩轩想知道对于每张工单他是否需要给别人提供原材料。是输出Yes,否输出No。考场思路20分当L1时只用计算轩轩的哪些邻居想干活儿即可。40分这种情况数据不是太大可以考虑一些正规算法了。我们拆解一下生产规则a 生产 L 阶段零件 → 需要 a 的邻居生产L-1阶段零件邻居生产L-1阶段零件 → 需要邻居的邻居生产L-2阶段零件……不断递归直到阶段 1此时对应工人需要原材料。轩轩1 号要提供原材料等价于存在一条路径起点 a终点 1路径恰好经过 L 条边。80分代码就是40分加记忆化#includebits/stdc.husingnamespacestd;intn,m,q;boolg[1005][1005];intf[1005][1005];booldfs(intu,ints,intv){if(s0){returnuv;}if(f[u][s]!-1)returnf[u][s];//剪枝for(inti1;in;i){if(g[u][i]){if(dfs(i,s-1,v)){returnf[u][s]1;}}}returnf[u][s]0;}intmain(){cinnmq;for(inti1;im;i){intu,v;cinuv;g[u][v]g[v][u]1;}while(q--){ints,L;cinsL;memset(f,-1,sizeof(f));if(dfs(s,L,1))//从s出发走L步到达1目标点v1{coutYesendl;}else{coutNoendl;}}return0;}正解轩轩怎样才能给原材料呢前面说过是他邻居生产1阶段的产品但是有一个十分有趣的地方当他邻居要生产3阶段的产品那么他就得生产2阶段的他邻居又得生产1阶段的他就可以给原材料。所以只要一个人与轩轩的最短距离和他想生产的阶段数的奇偶性相同且比它小那么轩轩就可以给原材料。翻译成非人语言就是在无向图中任意一条路径每多走一次往返边路径长度增加 2奇偶性保持不变。因此从 1 到 a 的路径分为偶数长度、奇数长度两类我们利用分层 BFS 分别求出两类的最短距离就能快速判定能否凑出长度恰好为 L 的路径。满分代码#includebits/stdc.husingnamespacestd;intn,m,q;ints,l;intdis[100005][2];vectorintg[100005];voidbfs(){memset(dis,0x3f,sizeof(dis));queuepairint,intque;que.push({1,0});dis[1][0]0;while(!que.empty()){intuque.front().first;intpque.front().second;que.pop();for(inti0;ig[u].size();i){intvg[u][i];intnpp^1;//翻转奇偶if(dis[v][np]dis[u][p]1){dis[v][np]dis[u][p]1;que.push({v,np});}}}}intmain(){cinnmq;for(inti0;im;i){intu,v;cinuv;g[u].push_back(v);g[v].push_back(u);}bfs();while(q--){cinsl;if(l%21){if(dis[s][1]l){coutYes;}else{coutNo;}}else{if(dis[s][0]l){coutYes;}else{coutNo;}}coutendl;}return0;}