【最短路】SSL_1297 GF打Dota
作者:互联网
题意
给出一张图,求出从点1到点n的次短路径。
思路
分别以起点和终点跑一次最短路,然后枚举一条边来绕长最短路变成次短路,更新答案。
代码
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
int n, m, tot = -1, p, ans;
int ver[100001], next[100001], head[100001], edge[100001];
int dis[10001], dise[10001], v[10001];
void add(int u, int v, int w) {
ver[++tot] = v;
next[tot] = head[u];
edge[tot] = w;
head[u] = tot;
}
void spfa() {
memset(dis, 127 / 3, sizeof(dis));
std::queue<int> q;
q.push(1);
v[1] = 1;
dis[1] = 0;
while (q.size()) {
int x = q.front();
q.pop();
v[x] = 0;
for (int i = head[x]; ~i; i = next[i]) {
int y = ver[i];
if (dis[x] + edge[i] < dis[y]) {
dis[y] = dis[x] + edge[i];
if (!v[y]) {
v[y] = 1;
q.push(y);
}
}
}
}
}
void spfaa() {
memset(v, 0, sizeof(v));
memset(dise, 127 / 3, sizeof(dise));
std::queue<int> q;
q.push(n);
v[n] = 1;
dise[n] = 0;
while (q.size()) {
int x = q.front();
q.pop();
v[x] = 0;
for (int i = head[x]; ~i; i = next[i]) {
int y = ver[i];
if (dise[x] + edge[i] < dise[y]) {
dise[y] = dise[x] + edge[i];
if (!v[y]) {
v[y] = 1;
q.push(y);
}
}
}
}
}
int main() {
memset(head, -1, sizeof(head));
scanf("%d %d", &n, &m);
for (int i = 1; i <= m; i++) {
int x, y, z;
scanf("%d %d %d", &x, &y, &z);
add(x, y, z);
add(y, x, z);
}
scanf("%d", &p);
spfa();
if (!p) printf("%d", dis[n]);
else {
ans = 2147483647;
spfaa();
for (int i = 0; i <= tot; i += 2) {
int x = ver[i ^ 1];
int y = ver[i];
int s = dis[x] + dise[y] + edge[i];
if (s > dis[n]) ans = std::min(ans, s);
s = dis[y] + dise[x] + edge[i];
if (s > dis[n]) ans = std::min(ans, s);
}
printf("%d", ans);
}
}
标签:head,int,SSL,Dota,edge,dise,ans,1297,dis 来源: https://blog.csdn.net/SSL_hzb/article/details/88077919