压缩旅行计划 题解
2025-03-09 10:29:07
发布于:北京
29阅读
0回复
0点赞
存图
注意读题,如果小明想要从 号城市跳到 号城市,则必须保证 。所以要用一个 vis 数组来存储某点 是否 。
dp
如何计算最少需要旅游多少城市呢?考虑 。
表示到点 最少需要旅游多少城市。
显然,如果 ,则 ,如果 为起点,则 。
接下来就是方程了, 从何而来?显然,如果与 连边且已经计算过的点就是可能的点。我们要在所有的点中找到旅游城市数量最少的点 。
所以说,状态转移方程式为:
最终答案就为 终点,即 。
总体评价
该算法的时间复杂度为 。
运行时间:37 ms.
占用内存:14.50MB.
比 bfs 解法好 114514 倍。
#include<iostream>
#include<algorithm>
#include<vector>
#include<unordered_map>
using namespace std;
#define ll long long
const ll MAXN=1e5+15;
const ll INF=0x7fffffff;
ll n,m,t,u,v;
ll a[MAXN],dp[MAXN];
bool vis[MAXN];
vector<ll> gra[MAXN];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>m>>t>>a[1];
vis[a[1]]=true;
for(int i=2;i<=t;i++){
cin>>a[i];
vis[a[i]]=true;
gra[a[i-1]].push_back(a[i]);
gra[a[i]].push_back(a[i-1]);
}
for(int i=1;i<=m-t+1;i++){
cin>>u>>v;
gra[u].push_back(v);
gra[v].push_back(u);
}
for(int i=1;i<=n;i++){
dp[i]=INF;
if(!vis[i]) continue;
if(i==a[1]){
dp[i]=1;
continue;
}
for(int j=0;j<gra[i].size();j++){
if(gra[i][j]>i) continue;
dp[i]=min(dp[gra[i][j]]+1,dp[i]);
}
}
cout<<dp[a[t]];
return 0;
}
完结撒花!
全部评论 1
呃呃呃好像你的题解耗时最多(
2024-07-07 来自 广东
0经过我114514年的学习后,我终于把它优化好了
2025-03-09 来自 北京
0
有帮助,赞一个