spfa算法----最短路
题目链接:https://cn.vjudge.net/contest/66569#problem/A
代码:
vis数组代表是否还有用,首先初始化为0,首先第一个点入队列,标记为1,然后刚入队列的时候,取消标记,如果经过判断之后还有用,就再标记。然后再就是出发点的路径,因为是从起始点开始走,所以从1-》1这个路径的权值就应该初始化为0.然后再就是对取最短路的判断,如果某一路径上找到了权重更短的路径,更改值,然后判断一下是否在队列中,如果没有,入队列,标记一下。
#include<iostream>
#include<string>
#include<cstring>
#include<iomanip>
#include<cmath>
#include<vector>
#include<queue>
using namespace std;
# define maxn 2000+10
# define inf 0x3f3f3f3f
int vis[maxn];
int path[maxn];
int a[maxn][maxn];
vector<pair<int,int > >wakaka[maxn];
queue<int >q;
int spfa(int t1,int t2)
{
memset(vis,0,sizeof(vis));
for(int i=1; i<=maxn; i++)
{
path[i]=inf;
}
q.push( t1);
vis[t1]=1;
path[t1]=0;
while(!q.empty())
{
int top=q.front();
q.pop();
vis[top]=0;
int len=wakaka[top].size();
for(int i=0; i<len; i++)
{
int temp=wakaka[top][i].first;
if(path[temp]>path[top]+wakaka[top][i].second)//这个地方比较的是目的地的已经存过的值和新的路径存过的值。
{
path[temp]=path[top]+wakaka[top][i].second;
if(vis[temp]==0)
{
vis[temp]=1;
q.push(temp);
}
}
}
}
return path[t2];
}
int main()
{
int t,n;
cin>>t>>n;
for(int i=1; i<=t; i++)
{
int u,v,w;
cin>>u>>v>>w;
if(w>a[u][v])
wakaka[u].push_back(make_pair(v,w));
wakaka[v].push_back(make_pair(u,w));
}
int t1=spfa(1,n);
cout<<t1<<endl;
return 0;
}
分割线----------------------------------------------------------------
最近做了点最短路的题,总结一下。
1,一定要注意最短路操作的是有向图还是无向图,虽然样例可能过,但是ac基本是不可能的。
2,注意打上标记数组,虽然对结果不会有太大的影响,如果数据量大起来的话,如果不打标记数组,队列会出现很多已经出现过的操作。