洛谷 P5663 加工零件

题目传送门

解题思路:

最暴力的做法:

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\n");
42     else printf("No\n");
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\n");
39     else printf("No\n");
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\n");
55             continue;
56         }
57         if(jd % 2 == 1 && ji[id] <= jd) {
58             printf("Yes\n");
59             continue;
60         }
61         if(jd % 2 == 0 && ou[id] <= jd) {
62             printf("Yes\n");
63             continue;
64         }
65         printf("No\n");
66     }
67     return 0;
68 }
正解

//CSP-J2019 T4

猜你喜欢

转载自www.cnblogs.com/lipeiyi520/p/11920956.html
今日推荐