P5663 [CSP-J2019] 加工零件
P5663 [CSP-J2019] 加工零件
思路
1.根据题意我们可以发现第\(a\)个工人想生产一个\(L\)阶段的零件就相当于从\(a\)点向相邻的工人走,没到一个工人等级减一 (不考虑往回传) 这不是就在图上走吗?
2.我们又发现每到一个点它就会往所有相邻的工人(节点)走,包括上一个。所以如果我们看单独看\(1\)号节点时会发现一个特性:当它第一次到达\(1\)号节点时所留给\(1\)号的阶段如果是偶数,那它必点最后回到该节点且要给原料,因此要输出Yes反之则为No
3.接着我们还能发现,当一个点到\(1\)号点有多条路径,则最短路能到达,自然就会产生影响,因此就把本体转换成了最短路。不过我们要求奇数长的最短路和偶数长的最短路,来应对不同情况
实施:
实施中的难点在于如何同时求两种不同的最短路,这里我们可以用分层图,因为学过数学的都知道奇数和偶数之间就差\(1\) 建一个新图之后从原图到新图就要花费一距离
因此在建图时在这些路中添加路径:
\[[u,v+n] [v,u+n] [v+n,u] [u+n,v]
\]
最后跑一遍最短路即可(这里数据很小选用适合的最短路算法即可)
跑完后
当\(L\)为奇数:如果 \(dis[a+n]>L\) 时为 \(No\) 反之 \(Yes\)
当\(L\)为偶数:如果 \(dis[a]>L\) 时为 \(No\) 反之 \(Yes\)
#include
#define maxn 200010
#define int long long
using namespace std;
struct edge{
int v,w;
edge(){}
edge(int inv,int inw):v(inv),w(inw){}
};
struct node{
int dis,u;
bool operator>(const node& a) const {return dis>a.dis;}
};
vector<edge>e[maxn];
int dis[maxn],vis[maxn];
priority_queue<node,vector<node>,greater<node>>q;
void dijkstra(int n,int s){
memset(dis,63,sizeof(dis));
dis[s]=0;
q.push({0,s});
while(!q.empty()){
int u=q.top().u;
q.pop();
if(vis[u])continue;
vis[u]=1;
for(auto ed:e[u]){
int v=ed.v,w=ed.w;
if(dis[v]>dis[u]+w){
dis[v]=dis[u]+w;
q.push({dis[v],v});
}
}
}
}
signed main(){
int n,m,q;
cin>>n>>m>>q;
for(int i=1;i<=m;i++){
int u,v;
cin>>u>>v;
e[u].push_back(edge(v+n,1));
e[v].push_back(edge(u+n,1));
e[u+n].push_back(edge(v,1));
e[v+n].push_back(edge(u,1));
}
dijkstra(n,1);
for(int i=1;i<=q;i++){
int a,l;
cin>>a>>l;
if(l&1){
if(dis[a+n]>l){
cout<<"No"<<endl;
}
else{
cout<<"Yes"<<endl;
}
}
else{
if(dis[a]>l){
cout<<"No"<<endl;
}
else{
cout<<"Yes"<<endl;
}
}
}
}
本文作者:XichenOC
本文链接:https://www.cnblogs.com/XichenOC/p/18682324
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
分类:
标签:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步