寻路问题:
思路:
从城市1开始深度优先遍历整个图,找到所有能到达N的走发,选出一个最优的。
于是得到如下代码(该代码由于超时不能ac):
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
int K, N, R;
struct Road {
int d, L, t;//路的终点、长度、过路费
};
vector<vector<Road>>G(110);//相当于一个二维数组
//G[i] 这个节点表示从i这个点延出去的边
int minLen;//最佳路径长度
int totalLen;//正在探索的路已经走了多长
int totalCost;//长在探索的这条路已经花了多少钱
int visited[110];//标志数组,用来表示城市有没有走过
void dfs(int s) {//从s点出发进行深度优先搜索
if (s == N) {
minLen = min(minLen, totalLen);
return;
}
for (int i = 0; i < G[s].size(); ++i) {
Road r = G[s][i];
if (totalCost + r.t > K)
continue;//钱不够回到循环,试下一条边
if (!visited[r.d]) {//判断是否走过
totalLen += r.L;
totalCost += r.t;
visited[r.d] = 1;
dfs(r.d);
visited[r.d] = 0;//撤销之前标记,防止影响别的走法
totalLen -= r.L;
totalCost -= r.t;
}
}
}
int main() {
cin >> K >> N >> R;
for (int i = 0; i < R; i++) {//读入数据
int s;
Road r;
cin >> s >> r.d >> r. L >> r.t;
if (s != r.d) {
G[s].push_back(r);
}
}
memset(visited, 0, sizeof(visited));//初始化为零
totalLen = 0;
minLen = 1 << 30;
totalCost = 0;
visited[1] = 1;
dfs(1);
if (minLen < (1 << 30)) {
cout << minLen << endl;
}
else
cout << "-1" << endl;
return 0;
}
但上传到oj平台上却因为超时而不能ac,于是便需要用到最优性剪枝,也就是多加几个判断条件来减少程序的运算量从而来减少所需时间。
本题多加的判断条件有:
(1)将当前的走过的总长度和之前找到的最优路径长度进行比较,如果当前的长度大于之前的最优路径长度就直接放弃该走法,不用走到低。
(2)自定义一个二维数组,用于存放中间计算结果的最优路径,也就是比较到达同一位置、所花相同的钱,所走的路程长度。
具体代码如下(此代码能ac):
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
int K, N, R;
struct Road {
int d, L, t;//路的终点、长度、过路费
};
vector<vector<Road>>G(110);//相当于一个二维数组
//G[i] 这个节点表示从i这个点延出去的边
int minL[110][10010];//记入城市和和钱的数目
//minL[i][j]从起点1到城市i花了j块钱
int minLen;//最佳路径长度
int totalLen;//正在探索的路已经走了多长
int totalCost;//长在探索的这条路已经花了多少钱
int visited[110];//标志数组,用来表示城市有没有走过
void dfs(int s) {//从s点出发进行深度优先搜索
if (s == N) {
minLen = min(minLen, totalLen);
return;
}
for (int i = 0; i < G[s].size(); ++i) {
Road r = G[s][i];
if (totalCost + r.t > K)
continue;//钱不够回到循环,试下一条边
if (!visited[r.d]) {//判断是否走过
if (totalLen + r.L >= minLen)//判断走到r.d的长度是否已经超过了之前不同走法的出来的minLen
continue;
if (totalLen + r.L >= minL[r.d][totalCost + r.t])//最优性剪枝,比较到达同一位置、所花相同的钱,所走的路程长度
continue;
minL[r.d][totalCost + r.t] = totalLen + r.L;//更新数据
totalLen += r.L;
totalCost += r.t;
visited[r.d] = 1;
dfs(r.d);
visited[r.d] = 0;//撤销之前标记,防止影响别的走法
totalLen -= r.L;
totalCost -= r.t;
}
}
}
int main() {
cin >> K >> N >> R;
for (int i = 0; i < R; i++) {//读入数据
int s;
Road r;
cin >> s >> r.d >> r.L >> r.t;
if (s != r.d) {
G[s].push_back(r);
}
}
memset(visited, 0, sizeof(visited));//初始化为零
totalLen = 0;
minLen = 1 << 30;
totalCost = 0;
visited[1] = 1;
for (int i = 0; i < 110; ++i)
for (int j = 0; j < 10010; ++j)
minL[i][j] = 1 << 30;//初始化置成一个大数
dfs(1);
if (minLen < (1 << 30)) {
cout << minLen << endl;
}
else
cout << "-1" << endl;
return 0;
}
大数据201 liyang