本文通过一道OJ题目来验证下面超链接中有关SPFA算法的内容
SPFA算法原理: http://blog.youkuaiyun.com/u010232171/article/details/42061823
题目超链接: http://hihocoder.com/contest/hiho25/problem/1
<span style="font-size:14px;">#include<queue>
#include<stdio.h>
using namespace std;
vector< pair<int,int> > graph[100010];
int arrdis[100010];
bool flag[100010];
int N,M,S,T;
queue<int> qe;
int main()
{
int key,val,disn,pnode,ft,pdis;
//初始化图,使用vector容器的数组+容器内的pair类型,其中数组下标表示起点,容器内的pair.first表示终点,pair.second表示点与点间距离
scanf("%d %d %d %d",&N,&M,&S,&T);
//fflush(stdin);
int s,t,dis;
for(int i=0;i<M;i++){
scanf("%d %d %d",&s,&t,&dis);
graph[s-1].push_back(make_pair(t-1,dis));
graph[t-1].push_back(make_pair(s-1,dis));
}
//初始化单源最短距离表
fill(arrdis, arrdis+N, 1000000007);
//将推入队尾加入队列
//同时记录该点已入队
qe.push(S-1);
arrdis[S-1]=0;
flag[S-1]=true;
//开始SPFA算法
while(!qe.empty()){
pnode=qe.front(); //出队
qe.pop();
pdis=arrdis[pnode];
flag[pnode]=false;
int sz=graph[pnode].size();
for(int i=0;i<sz;++i){ //扫描出队点的相关点
key=graph[pnode][i].first;
val=graph[pnode][i].second;
disn=pdis+val;
if(arrdis[key]>disn){ //更新距离
arrdis[key]=disn;
if(!flag[key]){ //更新队列
qe.push(key);
flag[key]=true;
}
}
//disk=disk>disn?disn:disk;
}
}
printf("%d\n",arrdis[T-1]);//输出题目要求的最短距离
return 0;
}</span>
上述代码通过了OJ,但在通过之前遇到多次TLM的问题,即超时。
在跟师兄讨论后,发现是输入数据部分占用了大量时间。在scanf语句后面使用fflush函数是想避免回车对输入的影响,这个问题之前确实有过,但是在本例的OJ中不会遇到。
所以,以后使用scanf时应该注意,不需要将过去习惯中的fflush函数添加。事实证明,fflush函数还是很耗时的,不加它t=143ms,加上它t=1450ms,这个数字是OJ给的。
另外一个就是大的数组应该定义为全局变量,如果定义为局部变量会出现 stack overflow的问题,这主要跟不同的变量所在的区域有关系。局部变量在栈区定义,而全局变量在堆区。