题目传送门
解题思路:
最暴力的做法:
bfs模拟,每次将一个阶段的所有点拿出来,将其所有直连的点都放进队列,知道本阶段结束,最后看1号点会不会在最后一个阶段被放入队列.(洛谷数据40分)
优化了一下代码:
上面的做法我用了两个队列,发现代码可以优化一下,用一个队列.(洛谷数据55分).
正解:
对于一个点,如果它加工的零件是偶数阶段,则在一定范围内与它偶数距离的点都要提供原料.
对于一个点,如果它加工的零件是奇数阶段,则在一定范围内与它奇数距离的点都要提供原料.
那么这个一定范围是多少呢?
就是小于等于这个点加工阶段大小的范围.
代码:

1 #include<iostream> 2 #include<cstdio> 3 #include<vector> 4 #include<cstring> 5 #include<queue> 6 7 using namespace std; 8 9 int n,m,qq,x,y; 10 bool vis[500001]; 11 queue<int> q,q1; 12 struct kkk{ 13 vector<int > a; 14 int len; 15 }e[100001]; 16 17 inline void solve() { 18 int id,s; 19 scanf("%d%d",&id,&s); 20 memset(vis,0,sizeof(vis)); 21 while(!q.empty()) q.pop(); 22 while(!q1.empty()) q1.pop(); 23 q.push(id); 24 vis[id] = 1; 25 while(s--) { 26 while(!q.empty()) { 27 int v = q.front(); 28 q.pop(); 29 vis[v] = 0; 30 if(e[v].len != 0) 31 for(int i = 0;i < e[v].len; i++) 32 q1.push(e[v].a[i]); 33 } 34 while(!q1.empty()) { 35 int ee = q1.front(); 36 vis[ee] = 1; 37 q1.pop(); 38 q.push(ee); 39 } 40 } 41 if(vis[1]) printf("Yes "); 42 else printf("No "); 43 } 44 45 int main() { 46 scanf("%d%d%d",&n,&m,&qq); 47 for(int i = 1;i <= n; i++) 48 e[i].len = 0; 49 for(int i = 1;i <= m; i++) { 50 scanf("%d%d",&x,&y); 51 e[x].len++;e[y].len++; 52 e[x].a.push_back(y); 53 e[y].a.push_back(x); 54 } 55 for(int i = 1;i <= qq; i++) 56 solve(); 57 return 0; 58 }

1 #include<iostream> 2 #include<cstdio> 3 #include<vector> 4 #include<cstring> 5 #include<queue> 6 7 using namespace std; 8 9 int n,m,qq,x,y; 10 bool vis[500001]; 11 queue<int> q; 12 struct kkk{ 13 vector<int > a; 14 int len; 15 }e[100001]; 16 17 inline void solve() { 18 int id,s; 19 scanf("%d%d",&id,&s); 20 memset(vis,0,sizeof(vis)); 21 while(!q.empty()) q.pop(); 22 q.push(id); 23 vis[id] = 1; 24 while(s--) { 25 int u = q.size(); 26 for(int i = 1;i <= u; i++) { 27 int v = q.front(); 28 q.pop(); 29 vis[v] = 0; 30 if(e[v].len != 0) 31 for(int i = 0;i < e[v].len; i++) { 32 if(vis[e[v].a[i]]) continue; 33 q.push(e[v].a[i]); 34 vis[e[v].a[i]] = 1; 35 } 36 } 37 } 38 if(vis[1]) printf("Yes "); 39 else printf("No "); 40 } 41 42 int main() { 43 scanf("%d%d%d",&n,&m,&qq); 44 for(int i = 1;i <= n; i++) 45 e[i].len = 0; 46 for(int i = 1;i <= m; i++) { 47 scanf("%d%d",&x,&y); 48 e[x].len++;e[y].len++; 49 e[x].a.push_back(y); 50 e[y].a.push_back(x); 51 } 52 for(int i = 1;i <= qq; i++) 53 solve(); 54 return 0; 55 }

1 #include<iostream> 2 #include<cstdio> 3 #include<queue> 4 #include<cstring> 5 6 using namespace std; 7 8 int n,m,qq,head[500001],ji[500001],ou[500001]; 9 bool flag; 10 struct kkk{ 11 int to,next; 12 }e[1000001]; 13 int tot; 14 queue<int> q; 15 16 inline void add(int x,int y) { 17 e[++tot].to = y; 18 e[tot].next = head[x]; 19 head[x] = tot; 20 } 21 22 inline void spfa() { 23 ou[1] = 0; 24 q.push(1); 25 while(!q.empty()) { 26 int s = q.front(); 27 q.pop(); 28 for(int i = head[s];i != 0; i = e[i].next) { 29 int t = e[i].to,jv = ji[t],ov = ou[t]; 30 ji[t] = min(ji[t],ou[s] + 1);//更新奇数最短路 31 ou[t] = min(ou[t],ji[s] + 1);//更新偶数最短路 32 if(jv != ji[t] || ov != ou[t]) 33 q.push(t); 34 } 35 } 36 } 37 38 int main() { 39 scanf("%d%d%d",&n,&m,&qq); 40 for(int i = 1;i <= m; i++) { 41 int x,y; 42 scanf("%d%d",&x,&y); 43 add(x,y); 44 add(y,x); 45 if(y == 1 || x == 1) flag = 1; 46 } 47 memset(ji,0x3f3f,sizeof(ji)); 48 memset(ou,0x3f3f,sizeof(ou)); 49 spfa(); 50 for(int i = 1;i <= qq; i++) { 51 int id,jd; 52 scanf("%d%d",&id,&jd); 53 if(!flag) { 54 printf("No "); 55 continue; 56 } 57 if(jd % 2 == 1 && ji[id] <= jd) { 58 printf("Yes "); 59 continue; 60 } 61 if(jd % 2 == 0 && ou[id] <= jd) { 62 printf("Yes "); 63 continue; 64 } 65 printf("No "); 66 } 67 return 0; 68 }
//CSP-J2019 T4