题意:给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()); }