【题目链接】

ybt 1985:【19CSPJ普及组】加工零件
洛谷 P5663 [CSP-J2019] 加工零件

【题目考点】

  1. 图论
  2. SPFA算法

【解题思路】

1. 问题分析

每个工人是一个顶点,传送带是边,构成一个图。轩轩是1号工人,即为1号顶点。被派工单的工人记为顶点a。

引理1:顶点v接到生产L阶段零件的任务。在顶点v的度不为0的前提下,如果L是偶数,那么顶点v需要提供原材料。
  • 证明:记顶点v的某一邻接点为u,v要生产L阶段的零件,那么u就要生产第L-1阶段的零件。u生产L-1阶段的零件又要求v生产L-2阶段的零件。依此类推,如果L是个偶数,u最终需要生产第1阶段的零件,v最终需要生产第0阶段的零件,即提供原材料。
引理2:顶点v接到生产L阶段的零件的任务,假设顶点v到1号顶点存在一条长度为n的路径,如果L >= n,且L - n是偶数,那么1号顶点需要为该任务提供原材料。
  • 证明:在这一路径上,与v相邻的顶点v1需要生产L-1阶段的零件,路径上与v1相邻的顶点需要生产L-2阶段的零件,一直传导到1号顶点,1号顶点需要生产L-n阶段的零件。根据引理1,如果L-n是偶数,那么1号顶点需要为该任务提供原材料。
定义1:顶点u到顶点v的奇数最短路径

顶点u到顶点v的长度为奇数的路径中,最短的路径。

定义2:顶点u到顶点v的偶数最短路径

顶点u到顶点v的长度为偶数的路径中,最短的路径。

2. 解题算法:

1. 求图上每一顶点到1号顶点的奇数最短路径的长度lodd与偶数最短路径的长度leven。

实现算法:SPFA算法

  1. 每个顶点v关联两个值:奇数最短路径长度v.lodd,偶数最短路径长度v.leven,初始值为无穷大。
  2. 1号顶点入队,1号顶点的偶数最短路径长度leven设为0。
  3. v相邻的点u的奇数最短路径长度,应该是min(v的偶数最短路径长度加1,u的奇数最短路径长度)。
    v相邻的点u的偶数最短路径长度,应该是min(v的奇数最短路径长度加1,u的偶数最短路径长度)。
    某顶点v出队后,遍历其所有相邻的顶点,设某相邻点为u,则如果u.lodd > v.leven + 1 或 u.leven > v.lodd + 1,那么改变u的对应的最短路径长度,并将u入队。如果不满足这两个条件,则不入队。
  4. 循环运行直到队空。此时与1号顶点连通的顶点的奇数最短路径和偶数最短路径就都设置完成了。

2. 查询结果

输入数据,v号顶点需要制造L阶段零件。

  1. 如果L是奇数,判断L >= v.lodd,如果为真,那么说明1号顶点需要生产L - v.lodd阶段的零件,L - v.lodd是偶数,因此1号顶点需要提供原材料。如果为假,则不需要提供原材料。
  2. 如果L是偶数,判断L >= v.leven,如果为真,那么说明1号顶点需要生产L - v.leven阶段的零件,L - v.leven是偶数,因此1号顶点需要提供原材料。如果为假,则不需要提供原材料。

【题解代码】

解法1:使用邻接表 (vector边表)

#include<bits/stdc++.h>
using namespace std;
#define N 100005
#define MAXINT 0x3f3f3f3f //表示无穷大,大于L的最大值10^9
//邻接表
int lodd[N], leven[N];
vector<int> edge[N];//边表
bool vis[N];
//求每一点到1号顶点的奇数最短路径长度和偶数最短路径长度
void initPathLength()
{memset(lodd, 0x3f, sizeof(lodd));memset(leven, 0x3f, sizeof(leven));int u, v;leven[1] = 0;//自己到自己的最短偶数路径长度为0queue<int> que;//队列保存顶点编号que.push(1);vis[1] = true;while(que.empty() == false){u = que.front();//出队的顶点u que.pop();vis[u] = false;for(int i = 0; i < edge[u].size(); ++i)//遍历u的邻接顶点 {v = edge[u][i];//v是u的邻接顶点if(lodd[v] > leven[u] + 1 || leven[v] > lodd[u] + 1){if(lodd[v] > leven[u] + 1)lodd[v] = leven[u] + 1;if(leven[v] > lodd[u] + 1)leven[v] = lodd[u] + 1;if(vis[v] == false){vis[v] = true;que.push(v);}}}}
}int main()
{int n, m, q, u, v, a, l;scanf("%d %d %d", &n, &m, &q);for(int i = 0; i < m; ++i){scanf("%d %d", &u, &v);//无向图添加边 edge[u].push_back(v);edge[v].push_back(u);}initPathLength();for(int i = 0; i < q; ++i){scanf("%d %d", &a, &l);if(l % 2 == 1 && l >= lodd[a] //如果l是奇数且大于等于a的奇数最短路径 || l % 2 == 0 && l >= leven[a]) //或如果l是偶数且大于等于a的偶数最短路径 printf("Yes\n");elseprintf("No\n");}return 0;
}

解法2:使用邻接表 (静态边链表)

#include<bits/stdc++.h>
using namespace std;
#define N 100005
#define MAXINT 1000000005 //表示无穷大,大于L的最大值10^9
//邻接表
typedef struct Ver//顶点
{int next;//下一个边结点的地址int lodd, leven;//奇数最短路径长度,偶数最短路径长度Ver(){next = 0;lodd = leven = MAXINT;//初始值为无穷大}
}Ver;
typedef struct Edg//边
{int verNum;//顶点编号int next;//下一个边结点的地址
}Edg;
Ver ver[N];//顶点数组
Edg edg[2*N];//边结点的结点池。边最多有10^5个,构造邻接表,每个边生成两个边结点,所以数组要开2N
int ep = 1;//edg数组待分配地址
//添加边,在边链表上用头插法
void addEdge(int u, int v)
{int lh, edgP;//lh:边链表的头 edgP:新的边结点lh = ver[u].next;//在结点u后面的边链表中添加边结点vedgP = ep++;//分配新的边结点edg[edgP].verNum = v;ver[u].next = edgP;edg[edgP].next = lh;lh = ver[v].next;//在结点v后面的边链表中添加边结点uedgP = ep++;//分配新的边结点edg[edgP].verNum = u;ver[v].next = edgP;edg[edgP].next = lh;
}
//求每一点到1号顶点的奇数最短路径长度和偶数最短路径长度
void initPathLength()
{int u, v;ver[1].leven = 0;//自己到自己的最短偶数路径长度为0queue<int> que;//队列保存顶点编号que.push(1);while(que.empty() == false){v = que.front();//出队的顶点v的地址que.pop();for(int p = ver[v].next; p != 0; p = edg[p].next)//遍历边链表,即遍历v周围的顶点u{u = edg[p].verNum;//u是v的邻接点的地址if(ver[u].lodd > ver[v].leven + 1 || ver[u].leven > ver[v].lodd + 1){if(ver[u].lodd > ver[v].leven + 1)ver[u].lodd = ver[v].leven + 1;if(ver[u].leven > ver[v].lodd + 1)ver[u].leven = ver[v].lodd + 1;que.push(u);}}}
}int main()
{int n, m, q, u, v, a, l;scanf("%d %d %d", &n, &m, &q);for(int i = 0; i < m; ++i){scanf("%d %d", &u, &v);addEdge(u, v);}initPathLength();for(int i = 0; i < q; ++i){scanf("%d %d", &a, &l);if(l % 2 == 0)//如果l是偶数{if(l >= ver[a].leven)printf("Yes\n");elseprintf("No\n");}else//如果l是奇数{if(l >= ver[a].lodd)printf("Yes\n");elseprintf("No\n");}}return 0;
}

信息学奥赛一本通 1985:【19CSPJ普及组】加工零件 | 洛谷 P5663 [CSP-J2019] 加工零件相关推荐

  1. 信息学奥赛一本通 1392:繁忙的都市(city) | 洛谷 P2330 [SCOI2005]繁忙的都市

    [题目链接] ybt 1392:繁忙的都市(city) 洛谷 P2330 [SCOI2005]繁忙的都市 [题目考点] 1. 图论 最小生成树 [解题思路] 将题目叙述转为图论概念,交叉路口为顶点,道 ...

  2. 信息学奥赛一本通 1375:骑马修栅栏(fence) | 洛谷 P2731 [USACO3.3]骑马修栅栏 Riding the Fences

    [题目链接] ybt 1375:骑马修栅栏(fence) 洛谷 P2731 [USACO3.3]骑马修栅栏 Riding the Fences [题目考点] 1. 图论:欧拉回路 欧拉回路存在的条件: ...

  3. 信息学奥赛一本通 ybt 1933:【05NOIP普及组】循环 | 洛谷 P1050 [NOIP2005 普及组] 循环

    [题目链接] ybt 1933:[05NOIP普及组]循环 洛谷 P1050 [NOIP2005 普及组] 循环 [题目考点] 1.高精度 2.数学 [解题思路] 要求最后k位的循环长度,可以从低位向 ...

  4. 信息学奥赛一本通 1937:【06NOIP普及组】数列 | 洛谷 P1062 [NOIP2006 普及组] 数列

    [题目链接] ybt 1937:[06NOIP普及组]数列 洛谷 P1062 [NOIP2006 普及组] 数列 [题目考点] 1. 数制 [解题思路] 如果k为2,那么这个数列 第1项为202^02 ...

  5. 信息学奥赛一本通 1961:【13NOIP普及组】计数问题 | 洛谷 P1980 [NOIP2013 普及组] 计数问题

    [题目链接] ybt 1961:[13NOIP普及组]计数问题 洛谷 P1980 [NOIP2013 普及组] 计数问题 [题目考点] 1. 数字拆分 [解题思路] 遍历1~n的各个数字,对每个数字做 ...

  6. 信息学奥赛一本通 1414:【17NOIP普及组】成绩 | 洛谷 P3954 [NOIP2017 普及组] 成绩

    [题目链接] ybt 1414:[17NOIP普及组]成绩 洛谷 P3954 [NOIP2017 普及组] 成绩 [题目考点] 1. 算术表达式 2. 自动类型转换 低精度类型与高精度类型计算结果是高 ...

  7. 信息学奥赛一本通 2006:【20CSPJ普及组】表达式 | 洛谷 P7073 [CSP-J2020] 表达式

    [题目链接] ybt 2006:[20CSPJ普及组]表达式 洛谷 P7073 [CSP-J2020] 表达式 [题目考点] 后缀表达式 表达式树 通过后缀表达式建立表达式树: 遍历后缀表达式字符串: ...

  8. 信息学奥赛一本通 1924:【03NOIP普及组】栈 | 洛谷 P1044 [NOIP2003 普及组] 栈

    [题目链接] ybt 1924:[03NOIP普及组]栈 洛谷 P1044 [NOIP2003 普及组] 栈 [题目考点] 递推.递归 栈 [解题思路]:一维递推 设数组a,a[i]表示i个数组成的数 ...

  9. 信息学奥赛一本通 1979:【18NOIP普及组】龙虎斗 | 洛谷 P5016 [NOIP2018 普及组] 龙虎斗

    [题目链接] ybt 1979: [18NOIP普及组]龙虎斗 洛谷 P5016 [NOIP2018 普及组] 龙虎斗 [题目考点] 1. long long类型使用 已知变量a, b是int类型的变 ...

最新文章

  1. 哪些品牌开始连接鸿蒙系统,华为鸿蒙系统硬件生态品牌升级为 HarmonyOS Connect
  2. ubuntu下机器学习工具的安装使用
  3. Hibernate 异常 Unable to instantiate default tuplizer
  4. c#竖直射线法判断点是否再多边形里面
  5. Ubuntu16.04 安装R与RStudio
  6. SAP系统中凭证涉及日期
  7. 【Python】核酸结果统计难?复旦博士生的操作火了......
  8. Android中GridView使用总结
  9. Dr. Evil Underscores(异或最大值最小)
  10. ospf避免环路_路由环路知识点总结!
  11. 手机App都在偷听我说话?窃听疑云全球密布,科技公司连连喊冤
  12. 通俗理解三维向量的点乘与叉乘
  13. kdj买卖指标公式源码_优化kdj买卖指标公式
  14. java中求矩形面积,java求矩形面积
  15. 2020 春节买火车票攻略和抢票工具分享
  16. 高效的APP在线制作平台,让梦想轻松孵化器
  17. 三相SVPWM逆变器MATLAB仿真实验,三相SVPWM逆变电路MATLAB仿真.doc
  18. AWS云迁移工具方法汇总
  19. Mac终端terminal光标快速移动方法 emacs/vim模式 | bash vim 、zsh vim模式
  20. [转]十年一覺程設夢[完整版]

热门文章

  1. 从一个基础Javascript面试题谈起
  2. 【转载】dotnet 线程同步
  3. 在中国,真正达到月收入1万以上的有多少
  4. 2018世界幸福指数中国排第86,这种报告是怎样做出来的?
  5. linux下dnw工具安装和使用
  6. python求解多元方程最优解_Python实现梯度下降算法求多元线性回归(二)
  7. 如果简历上真写了“会多线程”,那面试一般会被怎么问?
  8. 字节教育大裁员:有员工赔了一套首付款!
  9. 使用 guava-retrying 实现灵活的重试机制
  10. 你H第一次做的视频,在B站播放量过万了~