专栏文章
建图优化
个人记录参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mingc9gz
- 此快照首次捕获于
- 2025/12/02 01:57 3 个月前
- 此快照最后确认于
- 2025/12/02 01:57 3 个月前
分层图
首先讲讲如何分辨是不是分层图优化?
- 题目里面出现了一些特殊的位置是有传送等功能。
- 题目中对一些点流量限制。
分层图的实现逻辑(基于例题)
我们可以知道例题中,特殊的点是全部点,不过题目有次数限制,我们不用分层图十分复杂。
分层图嘛,顾名思义就是多个图叠在一起了,在这题中有次免费,我们就建层图,每个结点对下一层图中自己相邻的结点连单向边,不用代价。
接下来我们就可以直接在这么帅气的图上面跑一次最短路即可。
题目里限制了次免费,我们在这个图上面跑最短路,最多用免费,因为我们跑最短路时,代码走过去这个点以后就不能回去了,就类似一个3d的图,到了下一层就不能回去了。
最后输出的答案就是,层图中结点的最小值。(因题目而异,有可能是必须走完次的)
CPP#include<bits/stdc++.h>
using namespace std;
const int N=10005;
const int K=15;
const int INF=2147483647;
struct node{
int u,d;
bool operator<(const node&a)const{
return d>a.d;
}
};
vector<pair<int,int>> g[N*(K+1)];
int dis[N*(K+1)];
bool vis[N*(K+1)];
int n,m,k,s,t;
int main(){
cin>>n>>m>>k>>s>>t;
for(int i=0;i<m;i++){
int u,v,w;
cin>>u>>v>>w;
for(int j=0;j<=k;j++){
int uu=j*n+u,vv=j*n+v;
g[uu].push_back({vv,w});
g[vv].push_back({uu,w});
}
for(int j=0;j<k;j++){
int uu=j*n+u,vv=(j+1)*n+v;
g[uu].push_back({vv,0});
uu=j*n+v,vv=(j+1)*n+u;
g[uu].push_back({vv,0});
}
}
for(int i=0;i<=k*n+n;i++)dis[i]=INF;
dis[s]=0;
priority_queue<node> q;
q.push({s,0});
while(!q.empty()){
int u=q.top().u;
q.pop();
if(vis[u])continue;
vis[u]=1;
for(auto e:g[u]){
int v=e.first,w=e.second;
if(dis[v]>dis[u]+w){
dis[v]=dis[u]+w;
q.push({v,dis[v]});
}
}
}
int ans=INF;
for(int i=0;i<=k;i++)ans=min(ans,dis[i*n+t]);
cout<<ans;
return 0;
}
隐式建图
例题
给定两个不同的质数 和 (都是4位数),每次操作可以改变一个数字(),但改变后的数字必须是位数且仍是质数。
求从 到 的最少变换次数。如果无法到达,返回 。
很明显这道题目,无法把所有的边都建出来,我们可以不预先存储所有边,而是在djikstra时动态生成邻居连起就行了。
代码不放了
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...