问题描述:
N个城市,编号1到N。城市间有R条单向道路。
每条道路连接两个城市,有长度和过路费两个属性。
Bob只有K块钱,他想从城市1走到城市N。问最短共需要走多长的路。如果到不了N,输出-1
2<=N<=100
0<=K<=10000
1<=R<=10000
每条路的长度L, 1 <= L <= 100
每条路的过路费T , 0 <= T <= 100
输入:
K
N
R
s1e1L1T1
s1e2L2T2
...
sReRLRTR
s e是路起点和终点
解决办法:
数据结构|变量:
邻接表 (开始城市) 接着路(struct包含路的信息)(!注意:输入的数据会出现这样的错误,初始城市到达原城市)
数组 vistied[]深搜专用标记
minL[][] 优化(存储最短长度初始化为1<<30,下标分别是 到达城市、当前花费)
变量 minLen(就是答案)初始化为1<<30
totalLen当前长度
totalCost当前消费
过程:
DFS 传递参数是到达城市,终止条件就是判等N(符合找出所有能从1到N的路线),minLen选择totalLen中更小的数据和自己比较
深搜关键:for循环遍历邻接表,再dfs(到达城市节点)
优化条件:到达下一个城市(预估计)的
花费<K
长度<minLen||<minL[d][cost]
用continue终止(本次循环终止)
数据更新:以上变量及数组
dfs
弹回来了:把数据还原
代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
using namespace std;
int K, N, R;
struct Road
{
int d, L, t;
};
vector<vector <Road> > cityMap(110);
int minLen;
int totalLen;
int totalCost;
int visited[110];
int minL[110][10100];
void DFS(int s)
{
if(s == N)
{
minLen = min(minLen, totalLen);
return;
}
for(int i = 0; i < (int)cityMap[s].size(); i++)
{
int d = cityMap[s][i].d;
if(!visited[d])
{
int cost = totalCost + cityMap[s][i].t;
if(cost > K)
continue;
if((totalLen + cityMap[s][i].L >= minLen) || totalLen + cityMap[s][i].L >= minL[d][cost])
continue;
totalCost += cityMap[s][i].t;
totalLen += cityMap[s][i].L;
minL[d][cost] = totalLen;//?
visited[d] = 1;
DFS(d);
visited[d] = 0;
totalLen -= cityMap[s][i].L;
totalCost -= cityMap[s][i].t;
}
}
}
int main()
{
scanf("%d%d%d", &K, &N, &R);
for(int i = 0; i < R; i ++)
{
int s;
Road r;
scanf("%d%d%d%d", &s, &r.d, &r.L, &r.t);
if(s != r.d)
{
cityMap[s].push_back(r);
}
}
for(int i = 0; i < 110; i++)
for(int j = 0; j < 10100; j++)
minL[i][j] = 1 << 30;
memset(visited, 0, sizeof(visited));
totalCost = 0;
totalLen = 0;
visited[1] = 1;
minLen = 1 << 30;
DFS(1);
if(minLen == 1 << 30)
minLen = -1;
printf("%d\n", minLen);
return 0;
}