一道最短路问题,我是稍微变形一下dijkstra来做的
这道题不仅要求最短路,还要求最短路节点和的最大值。
这里有一个坑点就是存在多条最短路的时候要输出最短路径上节点和最大值
还有一个坑点就是这是一个无向图那么如果存在a->b的话那么b->a也是可以的
PS:这是蒻的第一道最短路,用的是priority_queue优化的dijkstra,时间复杂度O(nlogn)。
代码如下(记录前驱的代码我注释掉了因为对这题没什么用=。=):
#include <iostream>
#include <vector>
#include <queue>
#include <cstdio>
#include <cstring>
#define MAX_N 505
#define INF 0x7fffffff
using namespace std;
//边的顶点,权值
struct edge
{
int to, cost;
};
//first为最短距离,second为顶点
typedef pair<int, int> P;
vector<edge> G[MAX_N];
int a[MAX_N];
//顶点打表
int d[MAX_N];
//无向图记录used
bool used[MAX_N][MAX_N];
//记录前驱,用于记录路径
//int pre[MAX_N];
int n;
int ans[MAX_N];
void dijkstra(int s)
{
priority_queue<P, vector<P>, greater<P> > que;
fill(d, d + n, INF);
d[s] = 0;
que.push(P(0, s));
ans[s] = a[s];
while (!que.empty())
{
P temp = que.top();
que.pop();
int v = temp.second;
if (d[v] < temp.first)//小优化
continue;
for (int i = 0; i < G[v].size(); i++)
{
edge e = G[v][i];
if (used[v][e.to] || used[e.to][v])
continue;
if (d[e.to] > d[v] + e.cost)
{
d[e.to] = d[v] + e.cost;
// pre[e.to] = v;
ans[e.to] = ans[v] + a[e.to];
}
if (d[e.to] == d[v] + e.cost)
{
ans[e.to] = max(ans[e.to], ans[v] + a[e.to]);
}
que.push(P(d[e.to], e.to)); //优先队列,始终是权值最小的在队首
used[v][e.to] = true;
used[e.to][v] = true;
}
}
}
int main()
{
int m, start, end, x, y, z;
edge test0, test1;
memset(used, 0, sizeof(used));
cin >> n >> m >> start >> end;
for (int i = 0; i < n; i++)
scanf("%d", &a[i]);
for (int i = 0; i < m; i++)
{
scanf("%d %d %d", &x, &y, &z);
test0.to = y;
test0.cost = z;
test1.to = x;
test1.cost = z;
G[x].push_back(test0);
G[y].push_back(test1); //无向图记录边
}
dijkstra(start);
/*int tend = end;
ans += a[end];
ans += a[start];
while(pre[tend] != start)
{
ans += a[pre[tend]];
tend = pre[tend];
}*/
cout << d[end] << " " << ans[end] << endl;
return 0;
}