这题收获很大,求1到所有点的最短距离,然后再求所有点到1的最短距离,把所有的边反一下在求1到所有点的最短距离就是所有点到1的最短距离了.
刚开始用new直接就TLE了还以为是最短路算法问题,试了dijkstra还有spfa都是TLE,后来看了解题报告才发现必须要用静态邻接表才能过,
最后运行时间:dijkstra 290ms,spfa 280ms.还是spfa稍好一点,并且易于实现
#include <iostream>
#include <cstdio>
#include <memory.h>
#include <queue>
using namespace std;
const int maxn=1000010;
struct Edge{
int u,v,w,next;
}g[2][maxn];
struct node{
int i,v;
node(int ii=0,int vv=0):i(ii),v(vv){}
bool operator<(const node &rhs)const{
return v>rhs.v;
}
};
int n,q,dis[maxn],head[2][maxn];
bool vis[maxn];
/*
long long spfa(int idx){
long long ans=0;
queue<int>q;
memset(dis,0X45,sizeof(int)*(n+1));
memset(vis,0,n+1);
dis[1]=0;
q.push(1);
vis[1]=1;
while(q.size()){
int t=q.front();
q.pop();
vis[t]=0;
int ne=head[idx][t];
for (;ne!=-1;ne=g[idx][ne].next)
{
if(dis[g[idx][ne].v]>dis[t]+g[idx][ne].w){
dis[g[idx][ne].v]=dis[t]+g[idx][ne].w;
if(!vis[g[idx][ne].v]){
q.push(g[idx][ne].v);
vis[g[idx][ne].v]=1;
}
}
}
}
for (int i=1;i<=n;++i)
{
ans+=dis[i];
}
return ans;
}*/
long long dijkstra(int idx){
long long ans=0;
priority_queue<node>q;
memset(dis,0X45,sizeof(int)*(n+1));
memset(vis,0,n+1);
dis[1]=0;
q.push(node(1,0));
while(q.size()){
node t=q.top();
q.pop();
if(vis[t.i])continue;
vis[t.i]=1;
ans+=dis[t.i];
int ne=head[idx][t.i];
for (;ne!=-1;ne=g[idx][ne].next)
{
if(dis[g[idx][ne].v]>dis[t.i]+g[idx][ne].w&&!vis[g[idx][ne].v]){
dis[g[idx][ne].v]=dis[t.i]+g[idx][ne].w;
q.push(g[idx][ne].v);
}
}
}
return ans;
}
int main(){
int t;
scanf("%d",&t);
while (t--){
scanf("%d%d",&n,&q);
for (int i=0;i<=n;++i)
{
head[0][i]=head[1][i]=-1;
}
for (int i=0;i<q;++i)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
g[0][i].u=u;
g[0][i].v=v;
g[0][i].w=w;
g[0][i].next=head[0][u];
head[0][u]=i;
g[1][i].u=v;
g[1][i].v=u;
g[1][i].w=w;
g[1][i].next=head[1][v];
head[1][v]=i;
}
long long ans=dijkstra(0)+dijkstra(1);
printf("%lld\n",ans);
}
return 0;
}