POJ1511【前向星优化】
题目描述很有趣。。。。
SPFA
非常裸,但是要注意空间
程序:SPFA+前向星(优化内存)
写的很丑。。。但是很易懂
坑爹点:中间结果可以超过1000000000,INF不要开小了
最大的坑爹点:答案可以超过MAX_Longint,请自行前往64位
#include<stdio.h>
#include<stdlib.h>
struct graph
{
int s,t,w;
};
const int INF=1000000000;
struct graph a[1000001];//Graphic Prefix Star
struct graph b[1000001];//Mirror Graphic Prefix Star
int fsa[1000001];
int fsb[1000001];
int n,m;
int q[5000001];
int dist[1000001];
bool inq[1000001];
void qsort(struct graph array[],int l,int r)
{
int i=l,j=r;
int x=array[(l+r)/2].s;
while(i<=j)
{
while(array[i].s<x) i++;
while(array[j].s>x) j--;
if(i<=j)
{
array[0]=array[i];
array[i]=array[j];
array[j]=array[0];
i++;j--;
}
}
if(i<r) qsort(array,i,r);
if(l<j) qsort(array,l,j);
}
int main()
{
int i,j,k;
int T;
long long sum=0;
n=0;
scanf("%d",&T);
while(T--)
{
sum=0;
for(i=1;i<=n;i++)
fsa[i]=fsb[i]=0;
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
a[i].s=b[i].t=x;
a[i].t=b[i].s=y;
a[i].w=b[i].w=z;
}
qsort(a,1,m);
qsort(b,1,m);
for(i=1;i<=m;i++)
{
if(fsa[a[i].s]==0)
fsa[a[i].s]=i;
if(fsb[b[i].s]==0)
fsb[b[i].s]=i;
}
int head=0,tail=1;
q[tail]=1;
inq[1]=true;
for(i=1;i<=n;i++)
dist[i]=INF;
dist[1]=0;
while(head<tail)
{
head++;
i=fsa[q[head]];
while(a[i].s==q[head])
{
if(dist[q[head]]+a[i].w<dist[a[i].t])
{
dist[a[i].t]=dist[q[head]]+a[i].w;
if(!inq[a[i].t])
{
inq[a[i].t]=true;
q[++tail]=a[i].t;
}
}
i++;
}
inq[q[head]]=false;
}
for(i=1;i<=n;i++)
if(dist[i]!=INF)
sum+=dist[i];
head=0;
tail=1;
q[tail]=1;
inq[1]=true;
for(i=1;i<=n;i++)
{
dist[i]=INF;
inq[i]=false;
}
dist[1]=0;
while(head<tail)
{
head++;
i=fsb[q[head]];
while(b[i].s==q[head])
{
if(dist[q[head]]+b[i].w<dist[b[i].t])
{
dist[b[i].t]=dist[q[head]]+b[i].w;
if(!inq[b[i].t])
{
inq[b[i].t]=true;
q[++tail]=b[i].t;
}
}
i++;
}
inq[q[head]]=false;
}
for(i=1;i<=n;i++)
if(dist[i]!=INF)
sum+=dist[i];
printf("%I64d\n",sum);
}
return 0;
}