- 题意: 有向图,求点1到所有点来回最短路之和
- 思路: 跑两边最短路,一次正向存边,一次反向存边(相当于把其他点到源点的路倒着走了一遍?)
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<algorithm>
#include<map>
#define ll long long
#define FOR(i,l,r) for(int i = l ; i <= r ;++i )
#define inf 0x3f3f3f3f
#define EPS (1e-9)
#define ALL(T) T.begin(),T.end()
#define lson(i) i<<1
#define rson(i) (i<<1|1)
using namespace std;
template <class T>
inline bool scan_d(T &ret){
char c; int sgn;
if(c = getchar(),c==EOF) return 0;
while(c!='-'&&(c<'0'||c>'9')) c=getchar();
sgn=(c=='-')?-1:1;
ret=(c=='-')?0:(c-'0');
while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
ret*=sgn;
return 1;
}
typedef pair<int,int> pii;
const int maxn = 1e6+10;
int n,m;
int d[maxn],d2[maxn];
struct Edge{
int to,next,cost;
}edge[2][maxn*2];
int head[2][maxn],tot;
void addEdge(int u,int v,int w){
edge[0][++tot].to = v;
edge[0][tot].cost = w;
edge[0][tot].next = head[0][u];
head[0][u] = tot;
edge[1][++tot].to = u;
edge[1][tot].cost = w;
edge[1][tot].next = head[1][v];
head[1][v] = tot;
}
void init(){
for(int i=1;i<=n;++i){
d[i] = 0x3fffffff;
d2[i] = 0x3fffffff;
}
memset(head,0,sizeof(head));
tot = 0;
}
void dijkstra(){
priority_queue<pii,vector<pii>,greater<pii> > que;
d[1] = 0;
que.push(pii(0,1));
while(!que.empty()){
pii p = que.top(); que.pop();
int v = p.second;
if(d[v]<p.first ) continue;
for(int i=head[0][v];i;i=edge[0][i].next){
int u = edge[0][i].to;
if(d[u] > d[v] + edge[0][i].cost){
d[u] = d[v] + edge[0][i].cost;
que.push(pii(d[u],u));
}
}
}
}
void dijkstra2(){
priority_queue<pii,vector<pii>,greater<pii> > que;
d2[1] = 0;
que.push(pii(0,1));
while(!que.empty()){
pii p = que.top(); que.pop();
int v = p.second;
if(d2[v]<p.first ) continue;
for(int i=head[1][v];i;i=edge[1][i].next){
int u = edge[1][i].to;
if(d2[u] > d2[v] + edge[1][i].cost){
d2[u] = d2[v] + edge[1][i].cost;
que.push(pii(d2[u],u));
}
}
}
}
int main(){
int t;
scan_d(t);
while(t--){
scan_d(n); scan_d(m);
init();
int fr,to,w;
FOR(i,1,m){
scan_d(fr); scan_d(to); scan_d(w);
addEdge(fr,to,w);
}
dijkstra();
dijkstra2();
ll ans = 0;
FOR(i,2,n){
ans += d[i] + d2[i];
}
printf("%lld
",ans);
}
return 0;
}
用vector存图会tle,前向星加快读跑了1000ms就过了