题目含义
在一个图上,要从点s到点t,最多可以省去k条路的花费,问最少花费
题目分析
如果不看省去k条路花费的话,就是一个求最短路
考虑k条路花费的话,就是一个分层图
建立二维数组dis[maxn][k+1],具体的细节其实和求最短差不多
当然省去花费的路越多,花费越少,最后输出dis[t][k]就行了
对了,还要注意一下队列元素信息要包含坐过的免费次数le
题目代码
#include<iostream> #include<stdio.h> #include<string.h> #include<queue> using namespace std; const int maxn=1e4+7; const int INF=0x3f3f3f3f; typedef long long LL; int head[maxn],dis[maxn][12]; bool vis[maxn][12]; int tot,n,m,k,s,t,a,b,c; struct edge{ int to,w,next; }e[maxn*10]; struct node{ int pos,le,dis; bool operator<(const node &x)const{ return dis>x.dis; } }; void add(int u,int v,int w){ e[tot].to=v; e[tot].w=w; e[tot].next=head[u]; head[u]=tot++; } void Dijkstra(){ priority_queue<node>q; dis[s][0]=0; q.push((node){s,0,0}); while(!q.empty()){ node temp=q.top();q.pop(); int u=temp.pos,le=temp.le; if(vis[u][le])continue; vis[u][le]=true; for(int i=head[u];i!=-1;i=e[i].next){ int v=e[i].to; if(dis[v][le]>dis[u][le]+e[i].w){ dis[v][le]=dis[u][le]+e[i].w; if(!vis[v][le])q.push((node){v,le,dis[v][le]}); } if(le<k&&dis[v][le+1]>dis[u][le]){ dis[v][le+1]=dis[u][le]; if(!vis[v][le+1])q.push((node){v,le+1,dis[v][le+1]}); } } } } int main(){ scanf("%d%d%d",&n,&m,&k); scanf("%d%d",&s,&t); memset(head,-1,sizeof(head)); memset(vis,false,sizeof(vis)); memset(dis,INF,sizeof(dis)); tot=0; for(int i=1;i<=m;i++){ scanf("%d%d%d",&a,&b,&c); add(a,b,c),add(b,a,c); } Dijkstra(); printf("%d\n",dis[t][k]); return 0; }
原文:https://www.cnblogs.com/helman/p/11278820.html