[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\n");//如果step[n]的值没有被改变,直接输出-1 71 else printf("%d\n",step[n]);//若被改变,输出到达n的最小步数 72 } 73 }