P2939 [USACO09FEB] Revamping Trails G 题解
说要分层图,不会!
直接开始乱搞
考虑 DP。
AC code:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=10010;
const int K=30;
int n,m,k;
struct edge{
int v,w;
bool operator < (edge x) const{
return w>x.w;
}
};//结构体
vector<edge> g[N];
priority_queue<edge> pq;
int dis[N];
bool vis[N];
void dijkstra(){
memset(dis,0x3f,sizeof(dis));
dis[1]=0;
pq.push((edge){1,0});
while(!pq.empty()){
int near_point=pq.top().v; pq.pop();
if(vis[near_point]) continue;
vis[near_point]=true;
for(auto v:g[near_point]){
if(!vis[v.v]){
dis[v.v]=min(dis[near_point]+v.w,dis[v.v]);
pq.push((edge){v.v,dis[v.v]});
}
}
}
}//初始化
int dst[N][K];
void different_dijkstra(int x){
memset(vis,0,sizeof(vis));
pq.push((edge){1,0});
while(!pq.empty()){
int near_point=pq.top().v; pq.pop();
if(vis[near_point]) continue;
vis[near_point]=1;
// cout<<"near_point: "<<near_point<<' '<<dst[near_point][x]<<"\n";
for(auto v:g[near_point]){
dst[1][x]=1e9;
if(!vis[v.v]){
dst[v.v][x]=min(min(dst[near_point][x-1],dst[near_point][x]+v.w),dst[v.v][x]);
pq.push((edge){v.v,dst[v.v][x]});
}
}
}
}//处理答案
signed main(){
cin>>n>>m>>k;
for(int i=1;i<=m;i++){
int u,v,w; cin>>u>>v>>w;
g[u].push_back((edge){v,w});
g[v].push_back((edge){u,w});
}
dijkstra();
for(int i=1;i<=n;i++) dst[i][0]=dis[i];
for(int i=1;i<=k;i++){
for(int j=1;j<=n;j++) dst[j][i]=dst[j][i-1];
different_dijkstra(i);
}//依次计算
int ans=1e9;
for(int i=0;i<=k;i++) ans=min(ans,dst[n][i]);
//因为路径上不一定会用完k次修建次数,所以答案是dst[n]中的最大值。
cout<<ans;
return 0;
}