[POJ1724]ROADS
1 #include<iostream>
2 #include<limits.h>
3 #include<stdio.h>
4 #include<vector>
5 #include<string.h>
6 using namespace std;
7 inline int read()//快速读入
8 {
9 int sign=1,num=0;
10 char ch=getchar();
11 while(!isdigit(ch)){if(ch=='-')sign=-1;ch=getchar();}
12 while(isdigit(ch)){num=num*10+(ch-'0');ch=getchar();}
13 return sign*num;
14 }
15 int x,y,c,k,n,r,book[1010],step[1010],money[1010];
16 struct data{int l,t;}f;
17 vector<vector<vector<data > > > v;
18 void init()//初始化
19 {
20 memset(book,0,sizeof(book));
21 for(int i=1;i<=n;++i)
22 step[i]=INT_MAX;//limits.h
23 for(int i=1;i<=n;++i)
24 money[i]=INT_MIN;
25
26 v.clear();//多组数据,每次一定要clear
27
28 v.resize(n+1);//申请空间,否则无法在v[x][y]中push_back()
29 for(int i=0;i<=n;++i)
30 v[i].resize(n+1);
31 }
32 void dfs(int set,int dis,int spend)//set为当前位置,dis代表现在到达这里的距离,spend代表现在到达这里花费的距离
33 {
34 if(dis>step[n] || spend>k || (dis>=step[set] && money[set]<=spend))return;//剪枝
35 //注意:此处要保证步数(step)和花费(money)都要是最小
36 money[set]=spend;
37 step[set]=dis;
38 //更新money和step的值
39 if(set==n)return;
40 for(int i=1;i<=n;++i)//枚举城市
41 {
42 if(book[i])continue;
43 for(int j=0;j<v[set][i].size();++j)//枚举道路
44 {
45 book[i]=1;//记录城市已被走过
46 dfs(i,dis+v[set][i][j].l,spend+v[set][i][j].t);//尝试到达这个城市
47 book[i]=0;//回溯
48 }
49 }
50 }
51 int main()
52 {
53 c=read();
54 while(c--)
55 {
56 k=read();
57 n=read();
58 r=read();
59 init();
60 for(int i=1;i<=r;++i)
61 {
62 x=read();
63 y=read();
64 f.l=read();
65 f.t=read();
66 v[x][y].push_back(f);//数据是单向边,且城市a到城市b会有多条边
67 }
68 book[1]=1;
69 dfs(1,0,0);
70 if(step[n]==INT_MAX)printf("-1
");//如果step[n]的值没有被改变,直接输出-1
71 else printf("%d
",step[n]);//若被改变,输出到达n的最小步数
72 }
73 }