洛谷P3371

这是一个关于SPFA的题解。。(Dijkstra不太会。。)

由于邻接表太烦(不会),所以就直接写个vector来存边的关系,

然后用v[f][i].first表示f点连出去的第i个点的编号,v[f][i].second表示

f点连出去的第i条边的权值。所以,每次判断一下是否经过点i更优,并且更新

#include<bits/stdc++.h>
  
using
namespace std;

vector<pair<long,long> > v[500010];

long long st,n,m,s,x,y,z,d[10010],l[100010],vis[10010];//注意队列数组开大一些,因为每个点入队可能有好几次


int main(){
  scanf(
"%lld%lld%lld",&n,&m,&s);
  while(m--){

  scanf(
"%lld%lld%lld",&x,&y,&z);

   v[x].push_back(make_pair(y,z));
//建图,将边的关系存入v数组
  }
  for(int i=1;i<=n;i++)d[i]=2147483647;
  vis[s]
=1;//将s点标为已入队
  d[s]=0;//s到自己的距离当然是0
  l[0]=s;//s点入队
  int h=0,t=1;//注意队列数组开大一些,因为每个点入队可能有好几次
  while(h<t){//当队列中还有点时继续循环
  int f=l[h++];vis[f]=0;//初始化,将队头的点进行操作
  for(int i=0;i<v[f].size();i++)//枚举每条边
  if(d[v[f][i].first]>d[f]+v[f][i].second){//判断是否为更优
  d[v[f][i].first]=d[f]+v[f][i].second;/更新
  
if(!vis[v[f][i].first]) vis[v[f][i].first]=1,l[t++]=v[f][i].first;//更新后标为已入队
   }
  }
  for(int i=1;i<=n;i++)
  printf(
"%lld ",d[i]);
}
原文地址:https://www.cnblogs.com/heqingyu/p/7682329.html