Spfa

//spfa算的是从x到其他所有点的最短路

QAQ是一种求单源最短路的算法,判断负环非常资磁

 

 

 


 

用到的变量:

n:点的个数从1到n标号

/*

queue<int>q :一个队列,用stl或者手打,priority_queue也很资磁啊

head:队列头

tail:队列尾

bool vis[Maxm]:判断点是否被遍历过

to[Maxm] :to[i]是记录这条边是到哪个点的

next[Maxm]: next[i]是和i同一个起点出发的下一条边

last[Maxn] :last是记录最后一条边

w[Maxm] :w[i]是边权

*/

vector<int>to[100005],w[100005]:存图用的,to[1][1]=x就是第一个点出去的第一条边到的是X,w[]是边权

 

 

 

 


 

 

模板

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#define LiangJiaJun main
using namespace std;
int n,m,st,ed,h[100004],ne,dis[100004];
struct edge{
    int to,w,next;
}e[500004];
void insert(int u,int v,int w){
     e[++ne].to=v;
     e[ne].next=h[u];
     e[ne].w=w;
     h[u]=ne;
}
queue<int>q;
void spfa(int ask){
     memset(dis,127/3,sizeof(dis));
     q.push(ask);
     dis[ask]=0;
     while(!q.empty()){
        int x=q.front();q.pop();
        for(int i=h[x];i;i=e[i].next){
            if(dis[e[i].to]>dis[x]+e[i].w){
               dis[e[i].to]=dis[x]+e[i].w;
               q.push(e[i].to);
            }
        }
     }
}
int LiangJiaJun(){
    scanf("%d%d%d%d",&n,&m,&st,&ed);
    for(int i=1;i<=m;i++){
        int u,v,w;
        scanf("%d%d%d",&u,&v,&w);
        insert(u,v,w);insert(v,u,w);
    }
    spfa(st);
    printf("%d\n",dis[ed]);
    return  0;
}
dxy

 

#include<algorithm>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#define maxn 500005
using namespace std;
bool vis[maxn];
int dis[maxn],h[maxn];
int ecnt=0;
int n,m,s;
struct data
{
    int to,next,w;
}e[maxn];
void ins(int a,int b,int c)
{
    e[++ecnt].to=b;
    e[ecnt].next=h[a];
    h[a]=ecnt;
    e[ecnt].w=c;
}
queue<int>q;
void spfa(int ask){
    q.push(ask);
    memset(vis,0,sizeof(vis));
    memset(dis,127/3,sizeof(dis));
    dis[ask]=0;
    vis[ask]=1;
    while(!q.empty())
    {
        int x=q.front();q.pop();
        vis[x]=0;
        for(int i=h[x];i;i=e[i].next)
        {
            if(dis[e[i].to]>dis[x]+e[i].w)
            {
                dis[e[i].to]=dis[x]+e[i].w;
                if(!vis[e[i].to])
                {
                    vis[e[i].to]=1;
                    q.push(e[i].to);
                }
            }
        }
    }
}

int main()
{
    cin>>n>>m>>s;
    for(int a,b,c,i=1;i<=m;++i)
    {
        scanf("%d%d%d",&a,&b,&c);
        ins(a,b,c);
    }
    spfa(s);
    printf("%d",dis[i]);
    puts("");
    return 0;
}
SLF优化

 

 

 

 


 模板题

https://www.luogu.org/problem/show?pid=3371

实测比dij快了一倍多

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#define maxn 500005
using namespace std;
int n,m,s;
int ecnt;
int dis[10005];
int h[maxn];
struct node
{
    int to,w,next;
}e[maxn];
void ins(int a,int b,int c)
{
    e[++ecnt].to=b;
    e[ecnt].next=h[a];
    h[a]=ecnt;
    e[ecnt].w=c;
}
queue <int>q;
void spfa(int ask)
{
    memset(dis,0x3f,sizeof(dis));
    dis[ask]=0;
    q.push(ask);
    while(!q.empty())
    {
        int x=q.front();
        q.pop();
        for(int i=h[x];i;i=e[i].next)
        {
            if(dis[e[i].to]>dis[x]+e[i].w)
            {
                dis[e[i].to]=dis[x]+e[i].w;
                q.push(e[i].to);
            }            
        }
    }
}
int main()
{    
    cin>>n>>m>>s;
    int a,b,c;
    for(int i=1;i<=m;++i)
    {
        scanf("%d%d%d",&a,&b,&c);
        ins(a,b,c);
    }
    spfa(s);
    for (int k = 1; k <= n; k++) 
    {
        printf("%d ", dis[k] == 0x3f3f3f3f ? 2147483647 : dis[k]); 
    } 
    return 0;
}
View Code

 

posted @ 2016-08-25 19:31  pandaB  阅读(391)  评论(0编辑  收藏  举报