题目描述
凯凯的工厂正在有条不紊地生产一种神奇的零件,神奇的零件的生产过程自然也很神奇。工厂里有 \(n\) 位工人,工人们从 \(1 \sim n\) 编号。某些工人之间存在双向的零件传送带。保证每两名工人之间最多只存在一条传送带。
如果 \(x\) 号工人想生产一个被加工到第 \(L (L \gt 1)\) 阶段的零件,则所有与 \(x\) 号工人有传送带直接相连的工人,都需要生产一个被加工到第 \(L - 1\) 阶段的零件(但 \(x\) 号工人自己无需生产第 \(L - 1\) 阶段的零件)。
如果 \(x\) 号工人想生产一个被加工到第 1 阶段的零件,则所有与 \(x\) 号工人有传送带直接相连的工人,都需要为 \(x\) 号工人提供一个原材料。
轩轩是 1 号工人。现在给出 \(q\) 张工单,第 \(i\) 张工单表示编号为 \(a_i\) 的工人想生产一个第 \(L_i\) 阶段的零件。轩轩想知道对于每张工单,他是否需要给别人提供原材料。他知道聪明的你一定可以帮他计算出来!
输入格式
第一行三个正整数 \(n\),\(m\) 和 \(q\),分别表示工人的数目、传送带的数目和工单的数目。
接下来 \(m\) 行,每行两个正整数 \(u\) 和 \(v\),表示编号为 \(u\) 和 \(v\) 的工人之间存在一条零件传输带。保证 \(u \neq v\)。
接下来 \(q\) 行,每行两个正整数 \(a\) 和 \(L\),表示编号为 \(a\) 的工人想生产一个第 \(L\) 阶段的零件。
输出格式
共 \(q\) 行,每行一个字符串 \(Yes\) 或者 \(No\)。如果按照第 \(i\) 张工单生产,需要编号为 1 的轩轩提供原材料,则在第 \(i\) 行输出 \(Yes\);否则在第 \(i\) 行输出 \(No\)。注意输出不含引号。
输入输出样例
输入 #1
3 2 6
1 2
2 3
1 1
2 1
3 1
1 2
2 2
3 2
输出 #1
No
Yes
No
Yes
No
Yes
输入 #2
5 5 5
1 2
2 3
3 4
4 5
1 5
1 1
1 2
1 3
1 4
1 5
输出 #2
No
Yes
No
Yes
Yes
说明/提示
【输入输出样例 1 说明】
编号为 1 的工人想生产第 1 阶段的零件,需要编号为 2 的工人提供原材料。
编号为 2 的工人想生产第 1 阶段的零件,需要编号为 1 和 3 的工人提供原材料。
编号为 3 的工人想生产第 1 阶段的零件,需要编号为 2 的工人提供原材料。
编号为 1 的工人想生产第 2 阶段的零件,需要编号为 2 的工人生产第 1 阶段的零 件,需要编号为 1 和 3 的工人提供原材料。
编号为 2 的工人想生产第 2 阶段的零件,需要编号为 1 和 3 的工人生产第 1 阶段的零件,他/她们都需要编号为 2 的工人提供原材料。
编号为 3 的工人想生产第 2 阶段的零件,需要编号为 2 的工人生产第 1 阶段的零件,需要编号为 1 和 3 的工人提供原材料。
【输入输出样例 2 说明】
编号为 1 的工人想生产第 1 阶段的零件,需要编号为 2 和 5 的工人提供原材料。
编号为 1 的工人想生产第 2 阶段的零件,需要编号为 2 和 5 的工人生产第 1 阶段的零件,需要编号为 1,3,4 的工人提供原材料。
编号为 1 的工人想生产第 3 阶段的零件,需要编号为 2 和 5 的工人生产第 2 阶段的零件,需要编号为 1,3,4 的工人生产第 1 阶段的零件,需要编号为 2,3,4,5 的工人提供原材料。
编号为 1 的工人想生产第 4 阶段的零件,需要编号为 2 和 5 的工人生产第 3 阶段的零件,需要编号为 1,3,4 的工人生产第 2 阶段的零件,需要编号为 2,3,4,5 的工人生产第 1 阶段的零件,需要全部工人提供原材料。
编号为 1 的工人想生产第 5 阶段的零件,需要编号为 2 和 5 的工人生产第 4 阶段的零件,需要编号为 1,3,4 的工人生产第 3 阶段的零件,需要编号为 2,3,4,5 的工人生产第 2 阶段的零件,需要全部工人生产第 1 阶段的零件,需要全部工人提供原材料。
【数据规模与约定】
共 20 个测试点。
\(1 \leq u, v, a \leq n\)。
测试点 1~4,\(1 \leq n, m \leq 1000\),\(q = 3\),\(L = 1\)。
测试点 5~8,\(1 \leq n, m \leq 1000\),\(q = 3\),\(1 \leq L \leq 10\)。
测试点 9~12,\(1 \leq n, m, L \leq 1000\),\(1 \leq q \leq 100\)。
测试点 13~16,\(1 \leq n, m, L \leq 1000\),\(1 \leq q \leq 10^5\)。
测试点 17~20,\(1 \leq n, m, q \leq 10^5\),\(1 \leq L \leq 10^9\)。
思路
\(很容易可以想到没有环的情况,只需要判断奇偶性即可。为什么只需要判断奇偶性呢?我们可以想一下,假如说点 A 和点 B 之间有一条边相连,现在需要点 A 生产第7阶段的零件,那么 B 就要生产第6阶段的零件, A 又要生产第5阶段的零件,所以一条边走两遍就只需要判断奇偶性。因为每条边之间没有边权,我们可以假设都是1,这样就可以想到用BFS做。因为只需要判断路径的奇偶性,而且若路径长度过长(比如1号点跟3号点之间的距离是7,但是3号点只需要生产第3阶段的零件,这肯定就不行了)也不行,所以如果这两点之间的最短路过长就不满足条件了,不是最短路只要奇偶性一样,只要走两遍一条边就可以转换回去。所以只需要求出两点之间的奇最短路和偶最短路。由于我们只需要求出1号结点与其它结点的最短路,所以很明显是单源最短路。Dijkstra的原理是贪心,环的情况处理不了(我这个题用不行,可能是我菜QAQ)而SPFA的原理恰巧就是BFS。所以我们就可以用SPFA来求出1号结点与其它结点的奇最短路和偶最短路,再判断一下奇偶性就可以了。别忘记特判两点之间没有奇最短路或偶最短路的情况,这样就可以切掉这道题了。~~我居然用了3天时间才AK了去年的普及组的题目,还看了题解,我是垃圾。~~\)
代码
#include
#include
#include
#include
#include
#include
using namespace std;
const int N=100005,M=200005;
int edge[M],head[N],Next[M],ver[M],d[N];
bool v[N];
int t,n,m,tot;
int ou[N],ji[N];//汉语拼音QAQ
queue q;
void add(int x,int y){
ver[++tot]=y;
edge[tot]=1;
Next[tot]=head[x];
head[x]=tot;
}//存图
void SPFA(){
for(int i=0;i<=N-4;i++){
ou[i]=10000000;
}//为了便于判断有没有奇最短路或偶最短路,我存了10000000
for(int i=0;i<=N-4;i++){
ji[i]=10000000;
}
memset(v,0,sizeof(v));
ou[1]=0;
v[1]=1;
q.push(1);
while(!q.empty()){
int x=q.front();
q.pop();
v[x]=0;
for(int i=head[x];i;i=Next[i]){
int y=ver[i],z=1;
if(ou[x]+zl){
printf("No\n");
}//如果最短路距离过长,那么肯定不行
else{
if(ou[a]==10000000){
printf("No\n");//没有偶最短路
}
else{
printf("Yes\n");
}
}
}
else{
if(ji[a]>l){
printf("No\n");
}
else{
if(ji[a]==10000000){
printf("No\n");
}
else{
printf("Yes\n");
}
}
}
}
return 0;
}
对Dijkstra和SPFA认识的加深
\(一开始这个题我是用Dijkstra来做的,但是处理不了有环的情况(也有可能是我写错了),只得了35pts。但是我只改了这一个地方,就是把Dijkstra改成SPFA,它就神奇的A了,这也不得不引起我对这两个最短路算法的加深思考:到底最大的差别是什么?其实它们之间的代码几乎完全一样,只有两个差别:1.Dijkstra用的是小根堆来存储最短路,而SPFA用的是队列。2.Dijkstra不会重复标记点,即这个点我走过之后不会重复走。但是SPFA可以再将出队的点入队,这也是Dijkstra不能处理负边权而SPFA可以的原因。回归证明的原理,Dijkstra的原理是贪心,而SPFA是广搜。由于边权都是正的,所以Dijkstra在与当前点相连的边中取最小的加入小根堆并更新最短路,那么这个最短路肯定不会再被更新。因为如果它被更新,那肯定是这两点之间存在一个断点,使得两点分别到断点的距离之和小于直接相连。但是由于我选的是最短的那条边,所以起点与断点相连的那条边不可能更短,也就是不可能更新最短路。但反之,如果存在负边权,是存在这种情况的,所以出队的元素可能要再入队一遍来更新最小值。对这个题而言,由于是小根堆,它每次都是找最近的那个点然后走,那肯定不能绕一圈回来更新自己,但是SPFA可以,所以不能用Dijkstra而应该用SPFA。\)