百练+ 最短路径+spfa模版

点击打开链接
//DP和floyd有点像

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string>
#include<cstring>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<vector>
#define LL long long
#define inf 0x3f3f3f3f
#define mod 1e9+7
using namespace std;
const int maxn=1e3+5;
struct Node{
    int x,d;
};
vector<Node>Eg[maxn];
queue<Node> Q;
int d[maxn],N=0,Arr[maxn][maxn],cnt[maxn],ok=0;
void spfa(int s)
{
    int i=0;
    bool vis[maxn]={0};
    for(i=0;i<=N;i++) d[i]=inf;
    d[s]=0;
    memset(vis, 0, sizeof(vis));
    memset(cnt, 0, sizeof(cnt));
    while (!Q.empty()) Q.pop();
    Node temp1, temp2;
    temp1.x=s; temp1.d=d[s];
    cnt[temp1.x]+=1; ok=0;
    Q.push(temp1);
    while (!Q.empty()) {
        temp1=Q.front(); Q.pop();
        vis[temp1.x] =false;//清除在队列中的标志
        for(i=0; i<Eg[temp1.x].size();i++){
            temp2=Eg[temp1.x][i];
            if(d[temp1.x]+temp2.d<d[temp2.x]){
                d[temp2.x]=d[temp1.x]+temp2.d;
                if(!vis[temp2.x]){
                    vis[temp2.x]=true;//在队列中的标志
                    cnt[temp2.x]+=1;
                    Q.push(temp2);
                    if(cnt[temp2.x]>N){//有负环,队列超过N点
                        ok=1; return;
                    }
                }
            }
        }
    }
}
int main()
{
    int i=0,j=0,T=0,a=0,b=0,w=0;
    Node t1, t2;
    memset(Arr, inf, sizeof(Arr));
    scanf("%d %d",&T,&N);
    for(i=0;i<=N;i++) Eg[i].clear();
    for(i=0;i<T;i++){
        scanf("%d %d %d",&a, &b, &w);
        if(w<Arr[a][b]) Arr[a][b]=Arr[b][a]=w;
    }
    for(i=1;i<=N;i++){
        for(j=1;j<i;j++){
            if(Arr[i][j]<inf){
                t1.x=j; t1.d=Arr[i][j];
                Eg[i].push_back(t1);//  表示每个点链接的止点 和对应的边。
                t2.x=i; t2.d=Arr[i][j];
                Eg[j].push_back(t2);
            }
        }
    }
    spfa(1);
    printf("%d\n",d[N]);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值