这题思路和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);
}
}
浙公网安备 33010602011771号