题目链接
题意
给P个点Q条边的图,求所有点到1这个点的往返最短路之和。
思路
正向和反向分别存边,跑两遍dijkstra就可以了。
#include <iostream>
#include <cstdio>
#include <queue>
#include <string.h>
using namespace std;
#define INF 0x3f3f3f3f
typedef long long ll;
#define pr pair<int, int>
const int MAXN = 1e6 + 7;
int head[2][MAXN], to[2][MAXN], nex[2][MAXN], n, m;
int edge[2][MAXN], cnt1, cnt2;
int d[2][MAXN];
bool final[MAXN];
int s, e;
void add(int x, int y, int val, int op)
{
if(op == 1) {
to[op][++cnt2] = y;
edge[op][cnt2] = val;
nex[op][cnt2] = head[op][x];
head[op][x] = cnt2;
return;
}
to[op][++cnt1] = y;
edge[op][cnt1] = val;
nex[op][cnt1] = head[op][x];
head[op][x] = cnt1;
}
void dijkstra(int op)
{
memset(final, 0, sizeof(final));
for (int i = 1; i <= n; i++) d[op][i] = INF;
priority_queue<pr, vector<pr>, greater<pr> > q;
q.push(make_pair(0, s));//first是length,second是顶点
d[op][s] = 0;
while (!q.empty())
{
int u = q.top().second;
q.pop();
final[u] = true;
for (int i = head[op][u]; ~i; i = nex[op][i])
{
int v = to[op][i];
int len = edge[op][i];
if(!final[v] && d[op][v] > d[op][u] + len)
{
d[op][v] = d[op][u] + len;
q.push(make_pair(d[op][v], v));
}
}
}
}
int main()
{
int t;
cin >> t;
while (t--) {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) head[0][i] = head[1][i] = -1;
cnt1 = 0, cnt2 = 0;
for (int i = 1; i <= m; i++) {
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
add(x, y, z, 1); add(y, x, z, 0);//1 正向边,0 反向边
}
s = 1;
dijkstra(1);
dijkstra(0);
ll ans = 0;
for (int i = 2; i <= n; i++) {
ans += d[0][i] + d[1][i];
}
cout << ans << endl;
}
}