P5663 加工零件
P5663 加工零件
题解

暴力搜索
搜索显然会TLE
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<string>
#include<cstring>
#include<queue> using namespace std; typedef long long ll; inline int read()
{
int ans=;
char last=' ',ch=getchar();
while(ch<''||ch>'') last=ch,ch=getchar();
while(ch>=''&&ch<='') ans=ans*+ch-'',ch=getchar();
if(last=='-') ans=-ans;
return ans;
} const int maxn=1e5+;
struct node{
int to,nxt;
}edge[maxn*];
int head[maxn],cnt=;
int n,m,q;
bool vis[maxn];//节点i是否与1直接相连
int son[][];
int num[]; void addedge(int u,int v)
{
edge[++cnt].to =v;edge[cnt].nxt =head[u];head[u]=cnt;
edge[++cnt].to =u;edge[cnt].nxt =head[v];head[v]=cnt;
} void dfs(int sum,int u)
{
if(sum<) return;
if(num[]==) return;
for(int v,i=;i<=son[u][];i++){
v=son[u][i];
num[v]=min(num[v],sum);
dfs(sum-,v);
}
} int main()
{
n=read();m=read();q=read();
vis[]=;
for(int u,v,i=;i<=m;i++){
u=read();v=read();
if(u==) vis[v]=;
if(v==) vis[u]=;
son[u][++son[u][]]=v;
son[v][++son[v][]]=u;
addedge(u,v);
addedge(v,u);
}
for(int a,l,t=;t<=q;t++){
memset(num,,sizeof(num));
a=read();l=read();
if(l==){
if(a==||(!vis[a])) {
printf("No\n");
continue;
}
else if(vis[a]&&a!=) {
printf("Yes\n");
continue;
}
}else{
num[a]=l;
dfs(l-,a);
if(num[]==) printf("Yes\n");
else printf("No\n");
}
}
return ;
}
暴力搜索 40pt
考虑正解 SPFA最短路
题目给出一张无向图,他大概长这个亚子

对于给出一个点 a 要完成第 L 阶段任务,也就是从 a 到 1 找一条长度为 L 的路径
我们发现
1. 点2到1的距离为1(奇数),如果2完成奇数阶段任务,那么1就要为它提供原料,如果是偶数阶段任务就不用
2. 点5到点1的距离为2(偶数),如果5完成偶数阶段任务,那么1就要为它提供原料,如果是奇数阶段任务就不用
如果2到1的距离是5,也就是大于他们之间最短距离,那么要完成的阶段就会在二者之间不断传递(2-->5 , 1-->4 , 2-->3 , 1-->2 , ....),最后会变成上面分析的情况1
也就是说
1. 如果点a要完成的任务阶段数大于等于他们之间的最短距离,都可以化简成处理他们之间的最短距离来做
2. 如果a要完成的任务阶段数本就小于他们之间的最短距离,也就是a在扩展到1之前就已经有别的点为它提供原料,1节点自然不用提供原料
我们现在就要考虑上面说的第一种情况 L >= dis(a-->1)
由于从一个节点出发到达1会有很多路径,我们用 dis[ i ][ 0 ] 记录从节点 i 到节点 1 的长度为偶数的最短路的长度,用 dis[ i ][ 1 ] 记录从节点 i 到节点 1 的长度为奇数最短路的长度,SPFA 具体实现
更新数组的柿子也就是:
dis[ v ][ 0 ] = min ( dis[ v ][ 0 ] , dis[ u ][ 1 ] + 1 )
dis[ v ][ 1 ] = min ( dis[ v ][ 1 ] , dis[ u ][ 0 ] + 1 )
综上分析得出结论
1. 点 a 要完成的阶段任务数为偶数, 如果从a-->1存在一条偶数最短路,并且它的长度小于等于该任务数,1需要提供原料
2. 点 a 要完成的阶段任务数为奇数, 如果从a-->1存在一条奇数最短路,并且它的长度小于等于该任务数,1需要提供原料
3. 其余情况就不用1提供原料了
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<string>
#include<cstring>
#include<queue> using namespace std; typedef long long ll; int read()
{
int ans=;
char last=' ',ch=getchar();
while(ch<''||ch>'') last=ch,ch=getchar();
while(ch>=''&&ch<='') ans=ans*+ch-'',ch=getchar();
if(last=='-') ans=-ans;
return ans;
} const int maxn=1e5+;
int n,m,qus; struct node{
int to,nxt;
}edge[maxn<<];
int cnt=,head[maxn];
inline void addedge(int u,int v)
{
edge[++cnt].to =v,edge[cnt].nxt =head[u],head[u]=cnt;
edge[++cnt].to =u,edge[cnt].nxt =head[v],head[v]=cnt;
} int dis[maxn][];
bool vis[maxn]; inline void spfa()
{
queue<int>q;
memset(dis,,sizeof(dis));
memset(vis,,sizeof(vis));
dis[][]=;
vis[]=;
q.push();
while(!q.empty() ){
int u=q.front() ;
q.pop() ;
vis[u]=;
for(int v,i=head[u];i;i=edge[i].nxt ){
v=edge[i].to ;
if(dis[v][]>dis[u][]+){
dis[v][]=dis[u][]+;
if(!vis[v]){
q.push(v);
vis[v]=;
}
}
if(dis[v][]>dis[u][]+){
dis[v][]=dis[u][]+;
if(!vis[v]){
q.push(v);
vis[v]=;
}
}
}
}
} int main()
{
n=read();m=read();qus=read();
for(int u,v,i=;i<=m;i++){
u=read();v=read();
addedge(u,v);
}
spfa();
for(int a,l,i=;i<=qus;i++){
a=read();l=read();
if((l%)&&(dis[a][]<=l))printf("Yes\n");
else if((l%==)&&(dis[a][]<=l))printf("Yes\n");
else printf("No\n");
}
return ;
}
P5663 加工零件的更多相关文章
- 洛谷 P5663 加工零件
题目传送门 解题思路: 最暴力的做法: bfs模拟,每次将一个阶段的所有点拿出来,将其所有直连的点都放进队列,知道本阶段结束,最后看1号点会不会在最后一个阶段被放入队列.(洛谷数据40分) 优化了一下 ...
- 洛谷 P5663 加工零件 & [NOIP2019普及组] (奇偶最短路)
传送门 解题思路 很容易想到用最短路来解决这一道问题(题解法),因为两个点之间可以互相无限走,所以如果到某个点的最短路是x,那么x+2,x+4也一定能够达到. 但是如何保证这是正确的呢?比如说到某个点 ...
- P5663 加工零件 题解
原题链接 简要题意: 给定一个图,每次询问从 \(x\) 节点开始,\(y\) 步能不能达到 \(1\) 号节点. 算法一 这也是我本人考场算法.就是 深搜 . 因为你会发现,如果 \(x\) 用 \ ...
- 题解 P5663 【加工零件【民间数据】】
博客园体验更佳 讲讲我的做法 确定做法 首先,看到这道题,我直接想到的是递归,于是复杂度就上天了,考虑最短路. 如何用最短路 首先,看一张图 我们该如何解决问题? 问题:\(3\)做\(5\)阶段的零 ...
- 2019CSP-J T4 加工零件
题目描述 凯凯的工厂正在有条不紊地生产一种神奇的零件,神奇的零件的生产过程自然也很神奇.工厂里有 n 位工人,工人们从 1 ∼n 编号.某些工人之间存在双向的零件传送带.保证每两名工人之间最多只存在一 ...
- 题解 CSP2019-J2T4【加工零件】
这题我们要求的是啥呢?仔细读题可以发现,工人传送带的关系可以看成一个 \(n\) 个点和 \(m\) 条边的无向图,然后对于每组询问 \((a,L)\),其实就是问: \(1\) 到 \(a\) 有没 ...
- CSP-J2019 加工零件
Background: 之前 $noip $死了,泥萌都说 \(noip SPFA\) 了,现在 \(noip\) 复活了,所以 \(SPFA\) 也复活了. (注:这里的 \(noip\) 跟 \( ...
- 基础篇:3.2)规范化:3d零件建模
本章目的:规范化零件建模,这是机械的基本功夫. 1.建模的总体原则和总体要求 1.1 建模总体原则 a)零件模型应能准确表达零件的设计信息:b)零件模型包含零件的几何要素.约束要素和工程要素:c)零件 ...
- 2019年CPS-J复赛题解
题目涉及算法: 数字游戏:字符串入门题: 公交换乘:模拟: 纪念品:完全背包: 数字游戏:广搜/最短路. 数字游戏 题目链接:https://www.luogu.com.cn/problem/P566 ...
随机推荐
- git命令——revert、reset
参考:如何在 Git 中重置.恢复,返回到以前的状态 使用git时,如果对刚刚提交的后悔了怎么办,如何撤销? 方法一:手动修改 你把新增的文件删了 或者 更改过的文件再改回来,然后再commit一次. ...
- 【问题】man命令打开的手册上链接怎么展开?
参考:How to follow links in linux man pages? 前言 在使用man查看命令帮助的时候,有些文字下面会有下划线.给人的感觉是一个链接,但是又打不开.那么到底是不是链 ...
- git daemon 安装和使用
git daemon 安装和使用 系统:Cent OS 8 安装 git 和 git daemon(不同系统有不同的安装命令) yum install -y git yum install -y gi ...
- SpringBoot自动配置的魔法是怎么实现的
SpringBoot 最重要的功能就是自动配置,帮我们省去繁琐重复地配置工作.相信用过SpringBoot的人,都会被它简洁的步骤所惊讶.那么 SpringBoot 是如何实现自动配置的呢? 在这之前 ...
- Java8新特性--CompletableFuture
并发与并行 Java 5并发库主要关注于异步任务的处理,它采用了这样一种模式,producer线程创建任务并且利用阻塞队列将其传递给任务的consumer.这种模型在Java 7和8中进一步发展,并且 ...
- 45、[源码]-Spring容器创建-执行BeanFactoryPostProcessor
45.[源码]-Spring容器创建-执行BeanFactoryPostProcessor 5.invokeBeanFactoryPostProcessors(beanFactory);执行BeanF ...
- 如何安全的从LVM中移除磁盘
学习如何安全的从LVM中移除磁盘,当磁盘卷中有磁盘出现问题或是想把磁盘卷中的磁盘重新使用时就显得十分有用.本教程将重点关注以下问题: 如何安全的从LVM中移除磁盘 如何联机从VG中移除磁盘 如 ...
- [Zhx] 无题
https://www.luogu.org/problemnew/show/T15368 区间修改,区间查询k(<= 10)大值 应该也可以用分块写 #include <cstdio> ...
- TensorFlow(十八):从零开始训练图片分类模型
(一):进入GitHub下载模型-->下载地址 因为我们需要slim模块,所以将包中的slim文件夹复制出来使用. (1):在slim中新建images文件夹存放图片集 (2):新建model文 ...
- Xmind8安装
现在新版安装极其简单.是deb安装包Xmind8安装小书匠 kindle 参照官网安装方法,在此记录下来,方便自己查找. 流程: 55ccaad0655d256ac5fb9fea8aa8569d.pn ...