分层图,Dijkstra——HYSBZ - 2763

题目链接

题目含义

在一个图上,要从点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;
}

 

posted @ 2019-07-31 20:13  helman78  阅读(148)  评论(0编辑  收藏  举报