POJ 1724

我们用dis[i]表示目前i距离源点的最短距离

mo[i]表示在d[i]最优的前提下所花掉的钱

#include <cstdio>
#include <iostream>
#include <queue>
#include <string.h>
using namespace std;
#define INF 1<<30
#define N 110
#define M 10010
int first[N], w[M],v[M],next[M],toll[M];
int n,m,k,e;
struct node{
    int suml,money,ith;                                                  
    bool operator < (const node &rhs) const{
        return suml == rhs.suml ? money < rhs.money : suml > rhs.suml;
    }
    void init(int l,int m,int i){
        suml=l;
        money=m;
        ith=i;
    }
};
void init(){
    e=0;
    memset(first,-1,sizeof(first));
}
void addedge(int a,int b,int x,int y){
    v[e]=b;
    next[e]=first[a];
    w[e]=x;
    toll[e]=y;
    first[a]=e++;
}
int dijkstra(){
    int ans=INF;
    int dis[N]={0};
    int mo[N]={0};
    for(int i=0;i<=n;i++){
        dis[i]=INF;
        mo[i]=-1;
    }
    priority_queue<node> q;
    node lin,nex;
    lin.init(0,k,1);
    q.push(lin);
    while(!q.empty()){
        lin = q.top();
        q.pop();
        if(lin.ith == n)ans = min(ans,lin.suml);
        for(int i = first[lin.ith];i != -1;i = next[i]){
            if(lin.money >= toll[i] && lin.suml+w[i] < ans && (lin.suml+w[i] < dis[v[i]] || lin.money-toll[i] > mo[v[i]])){
                nex.init(lin.suml+w[i],lin.money-toll[i],v[i]);
                q.push(nex);
                if(lin.suml+w[i] < dis[v[i]] && lin.money-toll[i] > mo[v[i]]){
                    dis[v[i]] = lin.suml+w[i];
                    mo[v[i]] = lin.money-toll[i];
                }
            }
        }
    }
    return ans;
}
int main(){
    freopen("test.txt","r",stdin);
    int s,d,l,t;
        init();
        scanf("%d%d%d",&k,&n,&m);
        for(int i=0;i<m;i++){
            scanf("%d%d%d%d",&s,&d,&l,&t);
            addedge(s,d,l,t);
        }
        int ans=dijkstra();
        if(ans!=INF)printf("%d
",ans);
        else printf("-1
");
    return 0;
}



原文地址:https://www.cnblogs.com/Mr-Xu-JH/p/3877638.html