dijks
Posted wyh447154317
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了dijks相关的知识,希望对你有一定的参考价值。
堆优化
复杂度nlogn
type hhh=record z,w:longint; end; var cnt,i,j,k,a,b,ge,n,m,x,c:longint;//刚开始领接表数据开小了 d:array[0..500000]of longint; heap:array[-10..500090]of hhh; vist:array[0..500900]of boolean; pre,head,v,w:array[0..500009]of longint; procedure add(a,b,c:longint); begin inc(cnt);v[cnt]:=b;w[cnt]:=c;pre[cnt]:=head[a];head[a]:=cnt;end; procedure jia(a:longint); var i:longint; j:hhh; begin inc(ge); i:=ge; heap[ge].z:=d[a]; heap[ge].w:=a; while (i div 2)<>0 do if heap[i].z<heap[i div 2].z then begin j:=heap[i]; heap[i]:=heap[i div 2]; heap[i div 2]:=j; i:=i div 2; end else break; end; procedure jian; var min,i,k:longint; j:hhh; begin heap[1]:=heap[ge]; dec(ge); i:=1;k:=i*2; while (k)<=ge do begin if(k+1<=ge) and (heap[k+1].z<heap[k].z) then inc(k); if heap[k].z>heap[i].z then break else begin j:=heap[k];heap[k]:=heap[i];heap[i]:=j;end; i:=K;K:=I*2; end; end; procedure dijks(a:longint); var i,j,k,min,t,p,vv:longint; begin for i:=1 to n do d[i]:=100000000; fillchar(vist,sizeof(vist),false); d[a]:=0; jia(a); while ge>0 do begin t:=heap[1].w; k:=heap[1].z; if vist[t] then begin jian;continue;end;//排除重边的干扰 vist[t]:=true; jian; j:=head[t]; while j>0 do begin vv:=v[j]; if (d[vv]>k+w[j])and(not vist[vv]) then//可能重边 begin d[vv]:=k+w[j]; jia(vv); end; j:=pre[j]; end; end; end; begin readln(n,m,x); for j:=1 to m do begin readln(a,b,c); if a=b then continue; add(a,b,c); end; dijks(x); for j:=1 to n do begin if d[j]=100000000 then write(2147483647,‘ ‘) else write(d[j],‘ ‘);end; end .
非递归线段树 有时间好好看 顺便把他改成递归型
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn =10007; const int maxm = 500007; const int INF = 0x7fffffff; int n,m; inline int read() { int x=0; char c=getchar(); while(c<‘0‘||c>‘9‘) c=getchar(); while(c>=‘0‘&&c<=‘9‘) x=x*10+c-‘0‘,c=getchar(); return x; } struct node{ int v,next,w; }edge[maxm]; int num=0,head[maxn]; inline void add_edge(int a,int b,int c) { edge[++num].v=b;edge[num].w=c;edge[num].next=head[a];head[a]=num; } int dis[maxn],ans[maxn],s,t; int tree[maxn<<2],leaf; inline int check(int i,int j) { return dis[i]<dis[j]?i:j; } inline void build() { std::memset(dis,0x3f,sizeof dis);// for(int i=0;i<=n+1;i++) dis[i]=INF; for(leaf=1;leaf<=n;leaf<<=1);--leaf; for(int i=1;i<=n;++i)tree[leaf+i]=i; } inline void modify(int x,int y) { dis[x]=y,x+=leaf,x>>=1; while(x) tree[x]=check(tree[x<<1],tree[x<<1|1]),x=x>>1; } void dijkstra(int s) { build(); dis[s]=0; int u=s; for(int i=1;i<=n;++i) { ans[u]=dis[u]; const int disu=dis[u]; modify(u,INF); for(int j=head[u];j;j=edge[j].next){ int v=edge[j].v; if(dis[v]<INF&&dis[v]>disu+edge[j].w) modify(v,disu+edge[j].w); } u=tree[1]; } } inline void put(int x) { if (x > 9) put(x / 10); putchar(x % 10 + 48); } int main() { int k; n=read(),m=read(),k=read(); for(int a,b,c,i=1;i<=m;++i) { a=read(),b=read(),c=read(); add_edge(a,b,c); } dijkstra(k); for(int i=1;i<=n;++i) { if(dis[i]==0x3f3f3f3f)ans[i]=INF; // put(ans[i]), putchar(‘ ‘); printf("%d ",ans[i]); } return 0; }
以上是关于dijks的主要内容,如果未能解决你的问题,请参考以下文章
POJ-1135 Domino Effect---最短路Dijk
ZOJ-2750 Idiomatic Phrases Game---Dijk最短路
bzoj1922 sdoi2010 大陆争霸带限制性的dijks
[BZOJ1579] [Usaco2009 Feb]Revamping Trails 道路升级(分层图最短路 + 堆优化dijk)