1724

题目大意是:在一个有向图中,每条边有距离和费用两个参数,求从 1 到 N 点的费用和在不超过给定费用的情况下求最短路。

以 dijkstra 算法为基础,每次选择费用满足下具有最小距离的边.

#include <iostream>
#include <queue>
#include <vector>
#define MAXN 110
#define INF 1 << 29
using namespace std;
 
struct Node
{
    int id,dis,c;
    friend bool operator <(const Node &a,const Node &b)
{
   if(a.dis!=b.dis)
        return a.dis>b.dis;
    else
    return a.c>b.c;
}
};
 
int n,m,cmax;
int d[MAXN];
vector <Node> map[MAXN];
 
int dijkstra(int s)
{ 
    priority_queue<Node> p_q;   /* 优先级队列*/
 
    Node e={s,0,0},ne;
    int i,k,tmp,tc;
 
    d[s]=0;
    p_q.push(e);
 
    while(!p_q.empty())
    {
        e=p_q.top(); /* 每次筛出来的都是具有最小距离的边 */
        p_q.pop();
        d[e.id]=e.dis;
        if(e.id==n)
            return d[n];
        for(i=0;i<map[e.id].size();i++)  /* 对于和这个点相邻的邻边 */
        {
            k=map[e.id][i].id;
            tmp=e.dis+map[e.id][i].dis;
            tc=e.c+map[e.id][i].c;
            if(tc<=cmax) //总代价满足要求,不用判断!visit[i]&&tmp<d[k]
            {
                ne.id=k;
                ne.dis=tmp;
                ne.c=tc;
                p_q.push(ne);
            }
    }
}
if(d[n]!=INF)
    return d[n];
else 
    return -1;
}
 
int main()
{
    int i,j;
    int from,to,dis,cost;
    Node temp;
    while(scanf("%d",&cmax)!=EOF)
    {
        scanf("%d",&n);
        scanf("%d",&m);
        for(i=1;i<=n;i++)
        {
            map[i].clear();
            d[i]=INF;
        }
 
        for(i=0;i<m;i++) 
        {
            scanf("%d %d %d %d",&from,&to,&dis,&cost);
            temp.id=to;
            temp.dis=dis;
            temp.c=cost;
            map[from].push_back(temp);
        }
        printf("%d\n",dijkstra(1));  
    }
    return 0;  
}

原文地址:https://www.cnblogs.com/zhanglanyun/p/2050841.html