导航

POJ 1724 【存在附加约束的最短路问题】【优先队列】

Posted on 2015-09-20 19:25  tun~  阅读(193)  评论(0编辑  收藏  举报

题意:给K个权值。给含有N个点,R条单向边的图。

每条边都有两个权值,其中一个路长,另外一个是附加权值。

要求路的附加权值之和不超过K的情况下求最短路。

思路:

自己的思路太狭隘,这题还是看了大牛的思路。

利用优先队列,在附加权值不超限的前提下,把每个点通向的点都走,每次找出路长最短的点,如果找到第N个点则算法结束。

#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
int k,n,r,ednum;
struct edge
{
    int id,w,mon;
    edge *next;
};
edge *adj[105];
edge edges[10050];
struct st
{
    int id,mon,w;
    st(int a,int b,int c){id=a;mon=b;w=c;}
};
struct cmp
{
    bool operator()(const st &a,const st &b)
    {
        return a.w>b.w;
    }
};
inline void addEdge(int a,int b,int c,int d)
{
    edge *aa;
    aa = &edges[ednum];
    ednum++;
    aa->id=b;
    aa->w=c;
    aa->mon=d;
    aa->next=adj[a];
    adj[a]=aa;
}
int solve()
{
    priority_queue<st,vector<st>,cmp>q;
    for(edge *p=adj[1];p;p=p->next)
    {
        if(p->mon<k)
        {
            st tmp(p->id,p->mon,p->w);
            q.push(tmp);
        }
    }
    while(!q.empty())
    {
        st tmp=q.top();
        q.pop();
        if(tmp.id==n)
            return tmp.w;
        for(edge *p=adj[tmp.id];p;p=p->next)
        {
            if(p->mon+tmp.mon<=k)
            {
                st ttmp(p->id,p->mon+tmp.mon,p->w+tmp.w);
                q.push(ttmp);
            }
        }
    }
    return -1;
}
int main()
{
    int a,b,c,d;
//    ok=0;
    scanf("%d%d%d",&k,&n,&r);
    for(int i=1;i<=r;i++)
    {
        scanf("%d%d%d%d",&a,&b,&c,&d);
        addEdge(a,b,c,d);
    }
    printf("%d\n",solve());
}