[模板] 单源最短路径

来源:互联网 发布:能在淘宝上发布 植树 编辑:程序博客网 时间:2024/06/06 20:04

迪杰斯特拉 手写堆优化 一气呵成

//Writer:GhostCai && His Yellow Duck#include<iostream>#include<cstdio>#include<cstring>#define MAXN 500005using namespace std;struct Node{    int id,w;}node,r;Node hp[MAXN*2+5];long long size;inline void pus(long long id,long long w){    r.id=id;    r.w = w;    hp[++size]=r;    int now=size;    while(now>1){        if(hp[now>>1].w <=hp[now].w ) break;        swap(hp[now>>1],hp[now]);        now>>=1;    }}inline void del(){    hp[1]=hp[size--];    int now=1,next;    while(now<<1<=size){        next=now<<1;        if(next<size&&hp[next].w >hp[next+1].w ) next++;        if(hp[next].w >=hp[now].w ) break;        swap(hp[next],hp[now]);        now=next;    }}int head[MAXN],cnt;long long dis[MAXN];bool vis[MAXN];struct Edge{    int from,to,next,w;}e[MAXN*2];inline void add(int x,int y,int w){    e[++cnt].from = x;    e[cnt].to = y;    e[cnt].w =w;    e[cnt].next = head[x];    head[x]=cnt;}int m,n,st;inline void dij(){    for(register int i=1;i<=n;i++) dis[i]=2147483647;    dis[st]=0;    for(register int i=1;i<=n;i++){        if(i!=st){            pus(i,2147483647);        }    }    pus(st,0);    for(register int i=1;i<=n;i++){        long long mn,mnid;        do{            mnid=hp[1].id;            mn=hp[1].w ;            del();        }while(vis[mnid]);        vis[mnid]=1;        for(register int j=head[mnid];j!=-1;j=e[j].next){            dis[e[j].to]=min(dis[e[j].to],mn+e[j].w);            pus(e[j].to ,dis[e[j].to]);        }    }}int main(){    memset(head,-1,sizeof(head));    scanf("%d%d%d",&n,&m,&st);//  cin>>n>>m>>st;    int x,y,w;    for(int i=1;i<=m;i++){        scanf("%d%d%d",&x,&y,&w);//      cin>>x>>y>>w;        add(x,y,w);    }    dij();    for(int i=1;i<=n;i++){        printf("%lld ",dis[i]);//      cout<<dis[i]<<" ";    }}

迪杰斯特拉 STL版 好写 快

//Writer:GhostCai && His Yellow Duck#include<iostream>#include<cstdio>#include<cstring>#include<queue>#include<vector> #define MAXN 30000#define INF 2147483647 using namespace std;struct Node{    int id,v;     bool operator < (const Node &aa) const    {        return this->v > aa.v;    }}r,l;struct Edge{    int to,next,w;};vector<Edge> e;int head[MAXN];inline void add(int x,int y,int w){    Edge rr;    rr.next =head[x];    rr.to = y;    rr.w = w;    head[x]=e.size();    e.push_back(rr); }int m,n,st;long long dis[MAXN];bool vis[MAXN];inline void dij(int st){    priority_queue<Node> Q;    for(register int i=1;i<=n;i++) dis[i]=INF;    dis[st]=0;    for(register int i=1;i<=n;i++) if(i!=st) r.id = i,r.v = INF,Q.push(r);    r.id = st;    r.v = 0;    Q.push(r);     for(register int i=1;i<=n;i++){        do{            r=Q.top() ;            Q.pop() ;        }while(vis[r.id ]);        vis[r.id ]=1;        long long mn=r.v,mnid=r.id ;        for(int j=head[mnid];j!=-1;j=e[j].next){            dis[e[j].to]=min(dis[e[j].to],mn+e[j].w);            l.id = e[j].to ;            l.v = dis[e[j].to];            Q.push(l);         }    }}int main(){    scanf("%d%d%d",&n,&m,&st);//  cin>>n>>m>>st;    memset(head,-1,sizeof(head));    int x,y,w;    for(register int i=1;i<=m;i++){        scanf("%d%d%d",&x,&y,&w); //      cin>>x>>y>>w;        add(x,y,w);    }    dij(st);    for(register int i=1;i<=n;i++){        printf("%lld ",dis[i]);//      cout<<dis[i]<<" ";    }    return 0;}

神奇 SPFA

//Writer:GhostCai && His Yellow Duck#include<iostream>#include<cstdio>#include<cstring>#include<queue>#define MAXN 500005using namespace std;int m,n,st;int dis[MAXN];int cnode[MAXN];int head[MAXN],cnt;bool sta[MAXN];struct Edge{    int to,next,w;}e[MAXN]; void add(int x,int y,int w){    e[++cnt].to = y;    e[cnt].w = w;    e[cnt].next = head[x];    head[x]=cnt;}queue<int> Q;bool spfa(int st){    Q.push(st);    sta[st]=1;    int r;    while(!Q.empty()){        r=Q.front();        Q.pop();        sta[r]=0;        for(int i=head[r];i!=-1;i=e[i].next){            if(dis[e[i].to]>dis[r]+e[i].w){                dis[e[i].to]=dis[r]+e[i].w ;                if(!sta[e[i].to]){                    Q.push(e[i].to );                     sta[e[i].to ]=1;                    cnode[e[i].to]++;//同下                     if(cnode[e[i].to]>n) return 0;//判负环                 }            }        }    } }int main(){    memset(head,-1,sizeof(head));    scanf("%d%d%d",&n,&m,&st);//  cin>>n>>m>>st;    int x,y,w;    for(int i=1;i<=m;i++){        scanf("%d%d%d",&x,&y,&w);//      cin>>x>>y>>w;        add(x,y,w);    }    for(int i=1;i<=n;i++) dis[i]=2147483647;    dis[st]=0;    spfa(st);    for(int i=1;i<=n;i++) cout<<dis[i]<<" ";}