1. 程式人生 > 實用技巧 >乘車路線

乘車路線

題目描述

  • 編號為 1\sim N N 座城鎮用若干僅供單向行駛的道路相連,每條道路上均有兩個引數:道路長度( length )和在該條道路上行駛的費用( cost )。
  • BOB 準備從城鎮 1 出發到達城鎮 N ,但他目前只有 W 的錢,為此,你需要幫助他尋找一條從城鎮 1 到城鎮 N 在他能支付的前提下的一條最短路線。

輸入格式

  • W\ N\ M N 為城鎮數目, 2<=N<=100 M 為道路條數, 1<=M<=10000,W 為錢的數目, 0<=W<=1000
  • 隨後的 M 行每行為一條道路的資訊,包含 4 個數值( u,v,w,cost
    ),表示從城鎮 u v 有一條長度為 w 的單向道路,經過這條道路需要花費 cost 。( 1<=u,v<=N,1<=w<=100,0<=cost<=100

輸出格式

輸出最短長度,若無解,則輸出“

NO ”;

樣例

樣例輸入

5 6 7
1 2 2 3
2 4 3 3
3 4 2 4
1 3 4 1
4 6 2 1
3 5 2 0
5 4 3 2

樣例輸出

11

code

#include <bits/stdc++.h>
using namespace std;
const int maxn=100+10;
const int maxm=1e4+10;
const int INF=0x3f3f3f3f;
inline int read(){
	int k=0,f=1;char ch=getchar();
	for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
	for(;isdigit(ch);ch=getchar()) k=k*10+ch-'0';
	return k*f;
}
struct edge{int to,dis,next,cost;}e[maxm];
struct node{
	int x,cost,dis;
	bool operator < (const node& a)const{
		return dis > a.dis;
	}
};
int cnt=0;int head[maxn];
inline int add(int u,int v,int w,int cost){e[++cnt]=(edge){v,w,head[u],cost},head[u]=cnt;}
int d[maxn][maxn],vis[maxn][maxn];int ans=INF;int W,N,M;
void Dij(){
	priority_queue<node>q;q.push((node){1,0,0});
	memset(d,0x3f,sizeof(d));d[1][0]=0;	
	while(!q.empty()){
		node tmp=q.top();q.pop();
		int x=tmp.x,cst=tmp.cost;
		if(vis[x][cst])continue;
		vis[x][cst]=1;
		if(x==N)if(cst<=W)ans=min(ans,d[x][cst]);
		for(int i=head[x];i;i=e[i].next){
			int v=e[i].cost+cst,u=e[i].to;
			if(v>W)continue;
			if(!vis[u][v] && d[u][v]>d[x][cst]+e[i].dis){
				d[u][v]=d[x][cst]+e[i].dis,	q.push((node){u,v,d[u][v]});
			}
		}
	}
}
int main(){
	W=read(),N=read(),M=read();int u,v,dis,cost;
	for(int i=1;i<=M;i++)
        u=read(),v=read(),dis=read(),cost=read(),add(u,v,dis,cost);
	Dij();
	if(ans==INF) return printf("NO\n"),0;
	else return printf("%d\n",ans),(0 ^ 0);
}