雕刻时光

just do it……nothing impossible
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

SPFA-----静态链表优化+队列储存

Posted on 2011-02-15 08:57  huhuuu  阅读(403)  评论(0编辑  收藏  举报
主要优化通过静态链表的快速查找(用for()语句的话就会出现很多无谓的查找)
用队列是为了(不在队列的可疏松点)方便存储,下次接着出队再进行可疏松检验,最终达到最短路
View Code
#include<iostream>
#include
<queue>
using namespace std;
const long maxn=999999999;
const long edge_maxn = 10005; //边的最大上限
const long point_maxn = 105; //点的最大上限
struct node
{
int v;//终点
int w;//权值
int next;//同一起点的下一条边在edge数组中的位置
}edge[edge_maxn];
int pre[point_maxn];//以该点为起点的最后一条边存储在edge数组中的位置
int n;//点的数量
int m;//边的数量
queue<int>Q;
int dirs[point_maxn];//起点到i的最短距离
bool vis[point_maxn];//是否存在于队列
void Init()
{
memset(pre,
-1,sizeof(pre));
int x,y,z;
int index=1;
int i,j;
for(i=1;i<=m;i++)
{
scanf(
"%d%d%d",&x,&y,&z);
edge[index].v
=y;
edge[index].w
=z;
edge[index].next
=pre[x];
pre[x]
=index++;//保存x起点的最后一条边在edge数组中的位置
swap(x,y);
edge[index].v
=y;
edge[index].w
=z;
edge[index].next
=pre[x];
pre[x]
=index++;
}
}
void print(int end)
{
printf(
"%d\n",dirs[end]);
}
void SPFA()
{
int start=1;
int end=n;
while(!Q.empty())
{
Q.pop();
}

memset(vis,
0,sizeof(vis));
fill(dirs,dirs
+point_maxn,maxn);
dirs[start]
=0;
vis[start]
=1;
Q.push(start);
while(!Q.empty())
{
int top=Q.front();//边的起点
Q.pop();
vis[top]
=0;
for(int j=pre[top];j!=-1;j=edge[j].next)//pre[x]以该点为起点的最后一条边存储在edge数组中的位置
{
int e=edge[j].v;//边的终点
if(dirs[e]>edge[j].w+dirs[top])
{
dirs[e]
=edge[j].w+dirs[top];
if(!vis[e])
{
Q.push(e);
vis[e]
=1;
}
}
}
}
print(end);
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF && (n!=0 || m!=0))
{
Init();
SPFA();
}
return 0;
}