您的位置:首页 > 其它

pku 1511(最短路径,spfa静态邻接表)

2010-05-05 20:51 253 查看
给出图的有向边,求源点到其它所有点的最短距离之和sum1和其他点到源点的最短路径和sum2,sum1+sum2即为所求

按图中输入构造一个邻接表,然后将所有边转置后构造一个邻接表,用这两个表求两次最短路径,将他们的和相加即为结果

#include <iostream>
#include <queue>
using namespace std;
/*
传入源点s,numv存储点的个数,用dis数组存下最短路径值
edge[]为其邻接表
*/
class node
{
public:
int v,w;
node *next;
};
const int inf=0x7fffffff;
const int MAXN=1000005;
bool visit[MAXN];
int numv,pos;
int dis_1[MAXN],dis_2[MAXN];
node edge1[MAXN],edge2[MAXN],g[MAXN*2];
void add_edge(int &u,int &v,int &w)	//建立邻接表
{
node *ptr = &g[pos++];
ptr->v=v;
ptr->w=w;
ptr->next=edge1[u].next;
edge1[u].next=ptr;

node *ptr2 = &g[pos++];	//将所有边转置后的新表
ptr2->v=u;
ptr2->w=w;
ptr2->next=edge2[v].next;
edge2[v].next=ptr2;
}
void spfa(int s,int dis[],node edge[])
{
node *ptr;
int tmp,t,sz;
queue<int>    que;
dis[s] = 0;
que.push(s);
while(!que.empty())
{
tmp = que.front();
que.pop();
visit[tmp] = false;
for(ptr = edge[tmp].next;ptr!=NULL;ptr=ptr->next)
{
t = ptr->w;
if(dis[ptr->v] > dis[tmp]+t)
{
dis[ptr->v] = dis[tmp] + t;
if(!visit[ptr->v])  //若该点不在队列中,则入队,并修改相应的信息
{
visit[ptr->v] = true;
que.push(ptr->v);
}
}
}
}
}

int main()
{
int i,cas,q,u,v,w,j;
__int64 sum1,sum2;
node tmp;
scanf("%d",&cas);
while (cas--)
{
scanf("%d%d",&numv,&q);
sum1=0;	sum2=0;	pos=0;
for(i=1;i<=numv;++i)
{
visit[i] = false;
dis_1[i] = inf;
dis_2[i] = inf;
edge1[i].next=NULL;
edge2[i].next=NULL;
}				//init
for(i=0;i<q;++i)
{
scanf("%d%d%d",&u,&v,&w);
add_edge(u,v,w);
}						//构图
spfa(1,dis_1,edge1);
for(i=1;i<=numv;++i)
sum1+=dis_1[i];

spfa(1,dis_2,edge2);
for(i=1;i<=numv;++i)
sum2+=dis_2[i];
printf("%I64d/n",sum1+sum2);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: