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,注意打上标记数组,虽然对结果不会有太大的影响,如果数据量大起来的话,如果不打标记数组,队列会出现很多已经出现过的操作。
 

猜你喜欢

转载自blog.csdn.net/Let_life_stop/article/details/81228132