726:ROADS
查看 提交 统计 提问
总时间限制: 1000ms 内存限制: 65536kB
描述
N cities named with numbers 1 … N are connected with one-way roads. Each road has two parameters associated with it : the road length and the toll that needs to be paid for the road (expressed in the number of coins).
Bob and Alice used to live in the city 1. After noticing that Alice was cheating in the card game they liked to play, Bob broke up with her and decided to move away - to the city N. He wants to get there as quickly as possible, but he is short on cash.
We want to help Bob to find the shortest path from the city 1 to the city N that he can afford with the amount of money he has.
输入
The first line of the input contains the integer K, 0 <= K <= 10000, maximum number of coins that Bob can spend on his way.
The second line contains the integer N, 2 <= N <= 100, the total number of cities.
The third line contains the integer R, 1 <= R <= 10000, the total number of roads.
Each of the following R lines describes one road by specifying integers S, D, L and T separated by single blank characters :
S is the source city, 1 <= S <= N
D is the destination city, 1 <= D <= N
L is the road length, 1 <= L <= 100
T is the toll (expressed in the number of coins), 0 <= T <=100
Notice that different roads may have the same source and destination cities.
输出
The first and the only line of the output should contain the total length of the shortest path from the city 1 to the city N whose total toll is less than or equal K coins.
If such path does not exist, only number -1 should be written to the output.
样例输入
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
来源
CEOI 1998
展开
题意翻译
题面描述
有标号为1……n的城市与单行道相连。对于每条道路有两个与之相关的参数:道路的长度以及需要支付的费用(用硬币的数量表示)
鲍勃和爱丽丝曾经生活在城市1。在注意到爱丽丝在他们喜欢玩的卡牌游戏中作弊后,鲍勃决定与爱丽丝分手并搬走——去城市n。他希望尽快到达那里——越快越好,然而他现在有些现金短缺。 我们希望帮助鲍勃找到从城市1到城市n的一条最短路径——但他必须用他现有的钱支付得起。
输入输出格式
输入格式
输入的第一行含有一个整数t代表测试样例的组数。下面是t组测试样例。
对于每组测试数据,第一行含有一个整数K(0<=K<=10000),代表鲍勃所能支付得起的最大费用。
第二行含有一个整数N(2<=N<=100),代表城市总数。
第三行含有一个整数R(1<=R<=10000),代表道路的总数。
接下来R行每行用四个整数S,D,L,T,以单个空格分隔:
S表示出发点城市标号(1<=S<=N);
D表示目的地城市标号(1<=D<=N);
L是该道路的长度(1<=L<=100); T表示经过该道路的费用(0<=T<=100)。
注意不同的道路可能拥有相同的起点和终点。
输出格式
对于每组测试样例,输出单独的一行表示当花费小于等于K时最短路径的长度。如果不存在这样的路径,输出-1。
题目大意:求1点到n点在满足过路费小于这个人的钱数时,最短距离
这道题其实挺有意思的,看上去是个最短路径题,正解也是最短路径,但是一看到洛谷7000ms的时间限制,果断dfs
#include<iostream>
#include<cstring>
using namespace std;
struct edge{
int v,l,w,fail;
edge(){
}
edge(int a,int b,int c,int d){
v=a;
l=b;
w=c;
fail=d;
}
}e[2000000];
int head[110000],len;
void add(int a,int b,int c,int d){
e[len]=edge(b,c,d,head[a]);
head[a]=len++;
}
int n,m,k;
int ans=2147483646;
int vis[110000];
void dfs(int now,int totw,int totl){
// cout<<now<<" "<<totw<<" "<<totl<<endl;
if(totw>k||totl>ans)return;//最优性剪枝以及题目要求,如果答案大于已知最小值,放弃,如果过路费大于题目给定,放弃
if(n==now)ans=min(ans,totl);
for(int i=head[now];~i;i=e[i].fail){//枚举相邻点
int v=e[i].v;
if(!vis[v]){
vis[v]=1;
dfs(v,totw+e[i].w,totl+e[i].l);
vis[v]=0;//回溯
}
}
}
int main(){
int t;
cin>>t;
while(t--){
memset(head,-1,sizeof(head));
len=0;
memset(vis,0,sizeof(vis));
cin>>k>>n>>m;
for(int i=1;i<=m;i++){
int a,b,c,d;
cin>>a>>b>>c>>d;
add(a,b,c,d);
}
ans=2147483646;
vis[1]=1;
dfs(1,0,0);
if(ans!=2147483646)cout<<ans<<endl;
else cout<<-1<<endl;
}
}