这题思路和POJ 3268 是基本一样的,但数据规模很大,应当做如下处理:
数组要开大
SPFA若不用循环队列则队列要到10的七次方才比较稳妥
储存权值的空间要开成LONG LONG
就可以过了。
#include <stdio.h> #include <string.h> #define MAXN 1000000 #define MAXM MAXN #define inf 1000000000000000000 //18 int head[2][MAXN], pnt[2][MAXM], next[2][MAXM]; long long length[2][MAXM]; int tot[2]; long long dist[2][MAXN]; int queue[10000000]; int inq[MAXN]; int countq[MAXN]; int n,m,x; int a,b; long long len; void addedge(int func,int a,int b,long long len) { pnt[func][tot[func]]=b; length[func][tot[func]]=len; next[func][tot[func]]=head[func][a]; head[func][a]=tot[func]++; } int spfa(int func) { int qhead=0; int qtail=1; for (int i=0; i<n; i++) { inq[i]=0; countq[i]=0; dist[func][i]=inf; } dist[func][0]=0; queue[qhead]=0; while (qhead<qtail) { int idx=head[func][queue[qhead]]; while (~idx) { if(dist[func][queue[qhead]] + length[func][idx] < dist[func][pnt[func][idx]]) { dist[func][pnt[func][idx]] = dist[func][queue[qhead]] + length[func][idx]; if(!inq[pnt[func][idx]]) { inq[pnt[func][idx]]=1; countq[pnt[func][idx]]++; if(countq[pnt[func][idx]] > n+1) return 0; queue[qtail++]=pnt[func][idx]; } } idx=next[func][idx]; } inq[queue[qhead]]=0; qhead++; } return 1; } int main() { int ncase; scanf("%d",&ncase); while (ncase--) { scanf("%d%d",&n,&m); for(int i=0; i<2; i++) { for (int j=0; j<n; j++) { head[i][j]=-1; } for (int j=0; j<m; j++) { next[i][j]=-1; } tot[i]=0; } for(int i=0; i<m; i++) { scanf("%d%d%lld",&a,&b,&len); addedge(0,a-1,b-1,len); addedge(1,b-1,a-1,len); } spfa(0); spfa(1); long long ans=0; for(int i=1;i<n;i++) { ans+=dist[0][i]+dist[1][i]; } printf("%lld\n",ans); } }