题目描述
有一盗墓者潜入一金字塔盗宝。当她(难道是Lara Croft ?)打开一个宝箱的时候,突然冒出一阵烟(潘多拉的盒子?),她迅速意识到形势不妙,三十六计走为上计……由于她盗得了金字塔的地图,所以她希望能找出最佳逃跑路线。地图上标有N个室,她现在就在1室,金字塔的出口在N室。她知道一个秘密:那阵烟会让她在直接连接某两个室之间的通道内的行走速度减半。她希望找出一条逃跑路线,使得在最坏的情况下所用的时间最少。
输入格式
输入文件的第一行有两个正整数N(3≤N≤100)和M(3≤M≤2000);下面有M行,每行有三个数正整数U、V、W,表示直接从U室跑到V室(V室跑到U室)需要W(3≤W≤255)秒。
输出格式
输出所求的最少时间(单位为秒)。
输入
7 8
1 2 10
2 3 12
3 4 20
4 7 8
1 7 34
2 5 10
5 6 12
6 4 13
输出
66
思路:题目的意思是,找一个最短路,并且使最大的权值+最短路最小,首先可以套一个dijkstra模板,再单独一个数组来存最大值,因为存一起,不方便找出最大值来比较最后把两个数值加起来,得出答案
#include<queue>
#include<cstdio>
#include<cstring>
#define int long long
using namespace std;
bool vis[4005];
int dis[4005], e[4005];
int head[4005], next[4005], to[4005], w[4005], cnt;
struct node {
int now, s, maxn;
node() {}
node(int Now, int S, int Maxn) {
now = Now; s = S; maxn = Maxn;
}
};
int Max(int x, int y) { return x > y ? x : y; }
int Min(int x, int y) { return x < y ? x : y; }
void add(int x, int y, int s) {
to[++ cnt] = y;
w[cnt] = s;
next[cnt] = head[x];
head[x] = cnt;
}
queue<node> q;
bool operator <(node x, node y) {
return x.s > y.s;
}
void dijkstra(int begin) {
dis[begin] = 0;
q.push(node(begin, 0, 0));
while(!q.empty()) {
int now = q.front().now, s = q.front().s, maxn = q.front().maxn;
q.pop(); vis[now] = 0;
for(int i = head[now]; i; i = next[i]) {
int t = to[i], ma = Max(maxn, w[i]);
if(dis[t] + e[t] > dis[now] + w[i] + ma) {
dis[t] = dis[now] + w[i]; e[t] = ma;
q.push(node(t, s + w[i], ma));
}
}
}
}
signed main() {
int n, m, u, v, w;
scanf("%lld %lld", &n, &m);
memset(dis, 0x3f, sizeof(dis));
for(int i = 1; i <= m; i ++) {
scanf("%lld %lld %lld", &u, &v, &w);
add(u, v, w); add(v, u, w);
} dijkstra(1);
// for(int i = 1; i <= n; i ++) {
// printf("%d\n", dis[i]);
// }
printf("%lld", dis[n] + e[n]);
}