最短路模板

1.无优化dijkstra,

vis[i]代表是否已选入路径,第1模板题

#include<bits/stdc++.h>
using namespace std;
int n,m,s,tot=0,dis[10005],head[500005],mi,t;
bool vis[10005];
struct Edge{
      int next,to,w;
}h[500005];
void insert(int u,int v,int w){
    h[++tot].next=head[u];
    h[tot].to=v;
    h[tot].w=w;
    head[u]=tot;
}

void dijkstra(){
    for(int i=1;i<=n;i++)
        dis[i]=2147483647;
    dis[s]=0;
    for(int i=1;i<=n;i++){
        mi=214748364,t=-1;
        for(int j=1;j<=n;j++){
            if(!vis[j] && dis[j]<mi){
                mi=dis[j];
                t=j;
            }
        }
        if(t==-1) break;
        vis[t]=1;
        for(int j=head[t];j;j=h[j].next) {
            if(!vis[h[j].to])
                dis[h[j].to]=min(dis[h[j].to],h[j].w+dis[t]);
        }
    }
}
int main(){
    cin>>n>>m>>s;
    for(int i=1,u,v,w;i<=m;i++){
        cin>>u>>v>>w;
        insert(u,v,w);
    }
    dijkstra();
    for(int i=1; i<=n; i++)
        printf("%d ",dis[i]);
    return 0;
}

2.spfa vis[i]代表是否在队列队列,还可以退vis

#include<bits/stdc++.h>
const long long inf=2147483647;
const int maxn=10005;
const int maxm=500005;
using namespace std;
int n,m,s,cnt;
long long dis[maxn];
int vis[maxn],head[maxm];
struct Edge
{ int next,to,dis;
}e[maxm]; 
void insert(int u,int v,int w) { 
  e[++cnt].next=head[u];
  e[cnt].to=v; 
  e[cnt].dis=w; 
  head[u]=cnt; 
}
void spfa()
{
  queue<int> q;
  for(int i=1;i<=n;i++)
     dis[i]=inf;
  q.push(s); dis[s]=0; vis[s]=1;
  while(!q.empty())
  {
     int u=q.front(); 
     q.pop(); 
     for(int i=head[u]; i; i=e[i].next) 
     {   int v=e[i].to; 
         if(dis[v]>dis[u]+e[i].dis) //如果有最短路就更改
         {   dis[v]=dis[u]+e[i].dis;
             if(!vis[v]) //未入队则入队
             {  vis[v]=1; //标记入队
                q.push(v);
             }
         }
     }
     vis[u]=0; 
  }
}
int main(){
   cin>>n>>m>>s;
   for(int i=1; i<=m; i++){
      int u,v,w;
      cin>>u>>v>>w; 
      insert(u,v,w);}
   spfa();
   for(int i=1; i<=n; i++)
     if(s==i) cout<<0<<" ";
       else cout<<dis[i]<<" "; 
   return 0;
}

3.堆优化dijkstra

直接把dis按照瞬时值放入,就算更新也没办法,导致存在小的却在队列中故需优化。按需比较后放

#include <bits/stdc++.h>
#define ll long long
#define rep(i,x,y) for(register int i=x;i<=y;i++)
#define N 100005
#define M 500005
#define inf 2147483647
using namespace std;

inline int read(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-48;ch=getchar();}
    return x*f;}

int n,m,s,cnt,head[N],dis[N],vis[N];
struct node{int v,w,next;}e[M];
inline void insert(int u,int v,int w){
    e[++cnt]=(node){v,w,head[u]};head[u]=cnt;}

struct nodex{
    int u,d;
    bool operator <(const nodex& a)const{return d>a.d;}
};priority_queue<nodex> q;

inline void dijkstra(){
    rep(i,1,n) dis[i]=inf,vis[i]=0;
    dis[s]=0;
    q.push((nodex){s,0});
    while(!q.empty()){
        int u=q.top().u,d=q.top().d;q.pop();
        if(vis[u]) continue;//可能前面存在两条边同时扩展到了该节点,将其入队两次,需要弹出节省空间
        vis[u]=1;
        for(int i=head[u];i;i=e[i].next){
            int v=e[i].v,w=e[i].w;
            if(dis[u]+w<dis[v]){
                dis[v]=dis[u]+w;
                if(!vis[v])q.push((nodex){v,dis[v]});
            }
        }
    }
}
int main(){
//    freopen("1.in","r",stdin);
    n=read(),m=read(),s=read();
    for(int i=1;i<=m;i++){
        int x=read(),y=read(),z=read();
        insert(x,y,z);}
    dijkstra();
    rep(i,1,n) printf("%d ",dis[i]);
    return 0;
}

 

posted @ 2018-08-20 11:23  ASDIC减除  阅读(131)  评论(0编辑  收藏  举报