非常巧妙的题目
最短路逆求所有点到本点距离
#pragma GCC optimize(2)
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <string>
#include <cstring>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <ctime>
#include <vector>
#include <fstream>
#include <list>
#include <iomanip>
#include <numeric>
using namespace std;
typedef long long ll;
const int MAXN = 1e6 + 10;
const int INF = 0x3f3f3f3f;
ll next[MAXN], vsnext[MAXN], ans[MAXN], vsans[MAXN];
struct EDGE
{
ll next, to, val;
}edge[MAXN], vsedge[MAXN];
int head[MAXN], vshead[MAXN];
int cnt = 0;
void add(int x, int y, int z)
{
edge[++cnt].next = head[x];
edge[cnt].val = z;
edge[cnt].to = y;
head[x] = cnt;
vsedge[cnt].next = vshead[y];
vsedge[cnt].val = z;
vsedge[cnt].to = x;
vshead[y] = cnt;
}
struct bfsnode
{
ll now, dis;
bfsnode(ll x, ll y)
{
now = x, dis = y;
}
bool operator < (const bfsnode &b) const
{
return this->dis > b.dis;
}
};
bool finded[MAXN], vsfinded[MAXN];
void bfsone(bfsnode(x))
{
priority_queue <bfsnode> PQ;
PQ.push(x);
while(!PQ.empty())
{
bfsnode B = PQ.top();
PQ.pop();
if(!finded[B.now])
{
finded[B.now] = true;
ans[B.now] = min(ans[B.now], B.dis);
for(int i = head[B.now]; i != 0; i = edge[i].next)
{
PQ.push(bfsnode(edge[i].to, B.dis + edge[i].val));
}
}
}
}
void bfstwo(bfsnode(x))
{
priority_queue <bfsnode> PQ1;
PQ1.push(x);
while(!PQ1.empty())
{
bfsnode B = PQ1.top();
PQ1.pop();
if(!vsfinded[B.now])
{
vsfinded[B.now] = true;
vsans[B.now] = min(vsans[B.now], B.dis);
for(int i = vshead[B.now]; i != 0; i = vsedge[i].next)
{
PQ1.push(bfsnode(vsedge[i].to, B.dis + vsedge[i].val));
}
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int n, m, x, y, z, sum = 0;
cin>>n>>m;
for(int i = 0; i <= n; i++)
{
ans[i] = INF, vsans[i] = INF;
}
while(m--)
{
cin>>x>>y>>z;
add(x, y, z);
}
bfsone(bfsnode(1, 0) );
bfstwo(bfsnode(1, 0) );
for(int i = 1; i <= n; i++)
{
sum += (ans[i] + vsans[i]);
}
cout<<sum<<endl;
return 0;
}