题目类型 搜索题
题目意思
给出拥有的金钱 k ( 0 <= k <= 10000) 城市数量 n ( 2 <= n <= 100) 道路的数量 R ( 1 <= R <= 10000)
其中道路由四个变量 S D L T 描述 S 表示起点城市 D 表示终点城市 L 表示路的长度 T 表示经过这条路要收的过路费
现在问在不花费超过 k 的情况下从城市 1 到 n 最短的路径是多少
解题方法
DFS + 剪枝
当钱不够付过路费时终止 当目前的路径长度比前面搜到的最好的解要长时继续搜索下去已经不可能得到比之前更好的解了 回溯
注意题目的数据有点特别 用邻接表的头插法时间会很少 用 vector的push_back可能会导致超时
参考代码 - 有疑问的地方在下方留言 看到会尽快回复的
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
const int maxn = 100 + 10;
const int INF = 1<<30;
struct CNode { //保存邻接表的数组
int v, c, l, next;
}Node[100000];
int n, ans;
bool vis[maxn];
int M[maxn];
int count;
void DFS(int x, int len, int re) {
if(x == n) {
ans = min(ans, len);
return ;
}
if(len > ans) return ;
for( int i=M[x]; i!=-1; i=Node[i].next ) { // 邻接表访问
int v = Node[i].v;
if(re >= Node[i].c && !vis[v]) {
vis[v] = true;
DFS(v, len + Node[i].l, re - Node[i].c);
vis[v] = false;
}
}
}
int main() {
//freopen("in", "r", stdin);
int k, m;
while(scanf("%d", &k) != EOF) {
scanf("%d%d", &n, &m);
memset(M, -1, sizeof(M));
count = 0;
for( int i=0; i<m; i++ ) {
int a, b, c, d;
scanf("%d%d%d%d", &a, &b, &c, &d);
Node[count].next = M[a]; // 插入数据的操作 不明白为什么这样写的自己模拟下过程
Node[count].v = b, Node[count].c = d, Node[count].l = c;
M[a] = count++;
}
ans = INF;
memset(vis, 0, sizeof(vis));
vis[1] = 1;
DFS(1, 0, k);
if(ans == INF) printf("-1\n");
else printf("%d\n", ans);
}
return 0;
}