加工零件 题解
2023-09-07 22:27:47
发布于:广东
44阅读
0回复
0点赞
针对题意,原材料相当于第0阶段的零件、我们先假设1号工人轩轩与其他工人之间没有传送带的情况,那么显然,这种情况下,轩轩无法生产任何零件和原料,也不需要给其它工人提供原材料,答案显然是NO。
假设现在1号工人轩轩和i号工人有连边(双向传送带),那么当i号工人需要生产第1、3、5、7……2k+1阶段的零件的时候,1号工人轩轩分别需要提供第0(原材料)、2、4、6……2k阶段的零件,紧接着i号工人要提供给1号工人轩轩(总数量-2个)奇数阶段的零件,我们发现针对每一个奇数阶段的零件,轩轩都需要提供原材料。
当i号工人想生产偶数阶段的零件时,轩轩需要提供奇数阶段的零件,而如果1号工人轩轩需要偶数阶段的零件,那么i号工人需要提供奇数阶段的零件。
我们将之扩大为一条链:
偶数阶段 | 奇数阶段 | 偶数阶段 | 奇数阶段 |
---|---|---|---|
距离0 | 距离1 | 距离2 | 距离3 |
假设i号工人需要生产 L(L>0)阶段的零件
那么只要i->1之间存在一条长度<=L并且和L的奇偶性相同的路径,1号工人就必须生产原材料。
因此:对于一条双向边 1<--->U 我们将每个点1、U分别拆成两的点(奇点和偶点),边分解为交叉边,生成一张新图,对于新图:
所有从1(0)走向u(0)的路径,对应在原图中就是一条L为偶数的路径。
所有从1(0)走向u(1)的路径,对应在原图中就是一条L为奇数的路径。
为了降低复杂度,我们可以查找:
所有从1(0)走向u(0)的最短路径dist[u][0],所有从1(0)走向u(1)的最短路径dist[u][1]。问题就转化为单源最短路问题:
对于每次查询的A和 L
我们只需要做如下判断
L是偶数:则只要L>=dist[A][0];
L是奇数:则只要L>=dist[A][1];
AC代码
1.BFS(广度优先搜索)
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
# define N 100005
# define M 200005
int n, m, query;
int head[N],ver[M],Next[M],tot=-1;
int dist[N][2];
queue<pair<int ,int> > Q;
void ADD(int x,int y)
{
ver[++tot]=y;
Next[tot]=head[x];
head[x]=tot;
}
void bfs()
{
int x,y,t;
memset(dist, 0x3f, sizeof(dist));//初始化
Q.push(make_pair(1,0));
dist[1][0] = 0;
while (Q.size())
{
int x=Q.front().first,t = Q.front().second;
Q.pop();
for (int i = head[x];~i;i=Next[i])
{
y= ver[i];
if (dist[y][t^1]>dist[x][t]+1)
{
dist[y][t^1]=dist[x][t]+1;
Q.push(make_pair(y,t^1));
}
}
}
}
int main()
{
int x,y;
scanf("%d%d%d", &n, &m, &query);
memset(head, -1, sizeof(head));
for (int i=0;i<m;i++)
{
scanf("%d%d",&x,&y);
ADD(x,y);
ADD(y,x);
}
bfs();
while (query--)
{
int A, B;
scanf("%d%d", &A, &B);
if (A== 1 && head[1]==-1)puts("No");
else if (dist[A][B&1] <= B) puts("Yes");
else puts("No");
}
return 0;
}
2.Dijkstra(迪杰斯特拉算法)
#include <cstdio>
#include <cstring>
#include <iostream>
# include<queue>
#include <algorithm>
using namespace std;
# define N 100005
# define M 200005
int n, m, query;
int head[N],ver[M],Next[M],tot=-1;
int dist[N][2];
bool vis[N][2];
priority_queue<pair<int ,pair<int,int> > >Q;// 最短路径 <点,状态>
void ADD(int x,int y)
{
ver[++tot]=y;Next[tot]=head[x];head[x]=tot;
ver[++tot]=x;Next[tot]=head[y];head[y]=tot;
}
void dijkstra()
{
int x,y,t;
memset(dist, 0x3f, sizeof(dist));//初始化
dist[1][0] = 0;
memset(vis,0,sizeof(vis));
Q.push(make_pair(0,make_pair(1,0)));
while(Q.size())
{
x=Q.top().second.first;
t=Q.top().second.second;
Q.pop();
if(vis[x][t])continue;
vis[x][t]=1;
for(int i=head[x];~i;i=Next[i])
{
y=ver[i];
if(dist[y][t^1]>dist[x][t]+1)
{
dist[y][t^1]=dist[x][t]+1;
Q.push(make_pair(-dist[y][t^1],make_pair(y,t^1)));
}
}
}
}
int main()
{
int x,y;
scanf("%d%d%d", &n, &m, &query);
memset(head, -1, sizeof(head));
for (int i=0;i<m;i++)
{
scanf("%d%d",&x,&y);
ADD(x,y);
}
dijkstra();
while (query--)
{
int A, B;
scanf("%d%d", &A, &B);
if (A== 1 && head[1]==-1)puts("No");
else if (dist[A][B&1] <= B) puts("Yes");
else puts("No");
}
return 0;
}
3.spfa(队列优化算法)
#include <cstdio>
#include <cstring>
#include <iostream>
# include<queue>
#include <algorithm>
using namespace std;
# define N 100005
# define M 200005
int n, m, query;
int head[N],ver[M],Next[M],tot=-1;
int dist[N][2];
bool vis[N][2];
queue<pair<int ,int> >Q;// <点,状态>
void ADD(int x,int y)
{
ver[++tot]=y;Next[tot]=head[x];head[x]=tot;
ver[++tot]=x;Next[tot]=head[y];head[y]=tot;
}
void spfa()
{
int x,y,t;
memset(dist, 0x3f, sizeof(dist));//初始化
dist[1][0] = 0;
memset(vis,0,sizeof(vis));
vis[1][0]=1;
Q.push(make_pair(1,0));
while(Q.size())
{
x=Q.front().first;
t=Q.front().second;
Q.pop();
vis[x][t]=0;
for(int i=head[x];~i;i=Next[i])
{
y=ver[i];
if(dist[y][t^1]>dist[x][t]+1)
{
dist[y][t^1]=dist[x][t]+1;
if(!vis[y][t^1])
Q.push(make_pair(y,t^1));
}
}
}
}
int main()
{
int x,y;
scanf("%d%d%d", &n, &m, &query);
memset(head, -1, sizeof(head));
for (int i=0;i<m;i++)
{
scanf("%d%d",&x,&y);
ADD(x,y);
}
spfa();
while (query--)
{
int A, B;
scanf("%d%d", &A, &B);
if (A== 1 && head[1]==-1)puts("No");
else if (dist[A][B&1] <= B) puts("Yes");
else puts("No");
}
return 0;
}
这里空空如也
有帮助,赞一个