题目链接:http://poj.org/problem?id=1511
题目意思:在一个城市中,有P(1-1000000)个站点,并有Q(1-1000000)条路每条路(单向的)连接其中的两个站点,现在在1号站点,要请P-1个员工去每个站点传递一张单子,现在问你这些员工从1号站点出发去每个站点并且返回到1号站点要走过的最短路程!
题目数据量太大,处理时要加以注意。
代码:
#include<stdio.h>
#include<string.h>
#include<malloc.h>
#define INF 1000000000
typedef struct EdgeNode{
int v;
int w;
struct EdgeNode *next;
}EdgeNode;
typedef struct Vertex
{
int u;
EdgeNode *first;
}Ver;
Ver Vertex1[1000005],Vertex2[1000005];
__int64 dis[1000005];
int inq[1000005];
int n;
int P,Q;
int q[1000005];
int head,end;
void push(int x)
{
q[end]=x;
end++;
}
void pop()
{
head++;
}
int qempty()
{
if(head==end)
return 1;
return 0;
}
int gethead()
{
return q[head];
}
__int64 spfa(struct Vertex V[])
{
int i,x;
EdgeNode *r;
__int64 sum=0;
head=0;
end=0;
memset(inq,0,sizeof(inq));
for(i=2;i<=P;i++)
dis[i]=INF;
dis[1]=0;
push(1);
inq[1]=1;
while(!qempty())
{
x=gethead();
pop();
inq[x]=0;
for(r=V[x].first;r!=NULL;r=r->next)
{
if(dis[x]+r->w < dis[r->v])
{
dis[r->v]=dis[x]+r->w;
if(!inq[r->v])
{
push(r->v);
inq[r->v]=1;
}
}
}
}
for(i=2;i<=P;i++)
sum+=dis[i];
return sum;
}
void main()
{
int i;
int u,v,dis;
__int64 ans;
EdgeNode *p,*q;
scanf("%d",&n);
while(n--)
{
scanf("%d%d",&P,&Q);
for(i=1;i<=P;i++)
{
Vertex1[i].u=i;
Vertex1[i].first=NULL;
Vertex2[i].u=i;
Vertex2[i].first=NULL;
}
for(i=0;i<Q;i++)//建立邻接表(链表)
{
scanf("%d%d%d",&u,&v,&dis);
p=(EdgeNode *)malloc(sizeof(EdgeNode));
p->v=v;
p->w=dis;
p->next=Vertex1[u].first;
Vertex1[u].first=p;
q=(EdgeNode *)malloc(sizeof(EdgeNode));
q->v=u;
q->w=dis;
q->next=Vertex2[v].first;
Vertex2[v].first=q;
}
/*for(i=1;i<=P;i++)
{
q=Vertex1[i].first;
printf("%d->",Vertex1[i].u);
while(q!=NULL)
{
printf("%d(%d)->",q->v,q->w);
q=q->next;
}
printf("\n");
}*/
ans=0;
ans+=spfa(Vertex1);
ans+=spfa(Vertex2);
printf("%I64d\n",ans);
}
}