最短路径算法模板.docx

上传人:b****6 文档编号:3764253 上传时间:2022-11-25 格式:DOCX 页数:23 大小:21.25KB
下载 相关 举报
最短路径算法模板.docx_第1页
第1页 / 共23页
最短路径算法模板.docx_第2页
第2页 / 共23页
最短路径算法模板.docx_第3页
第3页 / 共23页
最短路径算法模板.docx_第4页
第4页 / 共23页
最短路径算法模板.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

最短路径算法模板.docx

《最短路径算法模板.docx》由会员分享,可在线阅读,更多相关《最短路径算法模板.docx(23页珍藏版)》请在冰豆网上搜索。

最短路径算法模板.docx

最短路径算法模板

1、图论—最短路径

1.1最短路径(单源bellman_ford邻接阵)

//单源最短路径,bellman_ford算法,邻接阵形式,复杂度O(n^3)

//求出源s到所有点的最短路经,传入图的大小n和邻接阵mat

//返回到各点最短距离min[]和路径pre[],pre[i]记录s到i路径上i的父结点,pre[s]=-1

//可更改路权类型,路权可为负,若图包含负环则求解失败,返回0

//优化:

先删去负边使用dijkstra求出上界,加速迭代过程

#defineMAXN200

#defineinf1000000000

typedefintelem_t;

intbellman_ford(intn,elem_tmat[][MAXN],ints,elem_t*min,int*pre){

intv[MAXN],i,j,k,tag;

for(i=0;i

min[i]=inf,v[i]=0,pre[i]=-1;

for(min[s]=0,j=0;j

for(k=-1,i=0;i

if(!

v[i]&&(k==-1||min[i]

k=i;

for(v[k]=1,i=0;i

if(!

v[i]&&mat[k][i]>=0&&min[k]+mat[k][i]

min[i]=min[k]+mat[pre[i]=k][i];

}

for(tag=1,j=0;tag&&j<=n;j++)

for(tag=i=0;i

for(k=0;k

if(min[k]+mat[k][i]

min[i]=min[k]+mat[pre[i]=k][i],tag=1;

returnj<=n;

}

1.2最短路径(单源dijkstra+bfs邻接表)

//单源最短路径,用于路权相等的情况,dijkstra优化为bfs,邻接表形式,复杂度O(m)

//求出源s到所有点的最短路经,传入图的大小n和邻接表list,边权值len

//返回到各点最短距离min[]和路径pre[],pre[i]记录s到i路径上i的父结点,pre[s]=-1

//可更改路权类型,但必须非负且相等!

#defineMAXN200

#defineinf1000000000

typedefintelem_t;

structedge_t{

intfrom,to;

edge_t*next;

};

voiddijkstra(intn,edge_t*list[],elem_tlen,ints,elem_t*min,int*pre){

edge_t*t;

inti,que[MAXN],f=0,r=0,p=1,l=1;

for(i=0;i

min[i]=inf;

min[que[0]=s]=0,pre[s]=-1;

for(;r<=f;l++,r=f+1,f=p-1)

for(i=r;i<=f;i++)

for(t=list[que[i]];t;t=t->next)

if(min[t->to]==inf)

min[que[p++]=t->to]=len*l,pre[t->to]=que[i];

}

1.3最短路径(单源dijkstra+bfs正向表)

//单源最短路径,用于路权相等的情况,dijkstra优化为bfs,正向表形式,复杂度O(m)

//求出源s到所有点的最短路经,传入图的大小n和正向表list,buf,边权值len

//返回到各点最短距离min[]和路径pre[],pre[i]记录s到i路径上i的父结点,pre[s]=-1

//可更改路权类型,但必须非负且相等!

#defineMAXN200

#defineinf1000000000

typedefintelem_t;

voiddijkstra(intn,int*list,int*buf,elem_tlen,ints,elem_t*min,int*pre){

inti,que[MAXN],f=0,r=0,p=1,l=1,t;

for(i=0;i

min[i]=inf;

min[que[0]=s]=0,pre[s]=-1;

for(;r<=f;l++,r=f+1,f=p-1)

for(i=r;i<=f;i++)

for(t=list[que[i]];t

if(min[buf[t]]==inf)

min[que[p++]=buf[t]]=len*l,pre[buf[t]]=que[i];

}

1.4最短路径(单源dijkstra+binary_heap邻接表)

//单源最短路径,dijkstra算法+二分堆,邻接表形式,复杂度O(mlogm)

//求出源s到所有点的最短路经,传入图的大小n和邻接表list

//返回到各点最短距离min[]和路径pre[],pre[i]记录s到i路径上i的父结点,pre[s]=-1

//可更改路权类型,但必须非负!

#defineMAXN200

#defineinf1000000000

typedefintelem_t;

structedge_t{

intfrom,to;

elem_tlen;

edge_t*next;

};

#define_cp(a,b)((a).d<(b).d)

structheap_t{elem_td;intv;};

structheap{

heap_th[MAXN*MAXN];

intn,p,c;

voidinit(){n=0;}

voidins(heap_te){

for(p=++n;p>1&&_cp(e,h[p>>1]);h[p]=h[p>>1],p>>=1);

h[p]=e;

}

intdel(heap_t&e){

if(!

n)return0;

for(e=h[p=1],c=2;c

h[p]=h[n--];return1;

}

};

voiddijkstra(intn,edge_t*list[],ints,elem_t*min,int*pre){

heaph;

edge_t*t;heap_te;

intv[MAXN],i;

for(i=0;i

min[i]=inf,v[i]=0,pre[i]=-1;

h.init();min[e.v=s]=e.d=0,h.ins(e);

while(h.del(e))

if(!

v[e.v])

for(v[e.v]=1,t=list[e.v];t;t=t->next)

if(!

v[t->to]&&min[t->from]+t->lento])

pre[t->to]=t->from,min[e.v=t->to]=e.d=min[t->from]+t->len,h.ins(e);

}

1.5最短路径(单源dijkstra+binary_heap正向表)

//单源最短路径,dijkstra算法+二分堆,正向表形式,复杂度O(mlogm)

//求出源s到所有点的最短路经,传入图的大小n和正向表list,buf

//返回到各点最短距离min[]和路径pre[],pre[i]记录s到i路径上i的父结点,pre[s]=-1

//可更改路权类型,但必须非负!

#defineMAXN200

#defineinf1000000000

typedefintelem_t;

structedge_t{

intto;

elem_tlen;

};

#define_cp(a,b)((a).d<(b).d)

structheap_t{elem_td;intv;};

structheap{

heap_th[MAXN*MAXN];

intn,p,c;

voidinit(){n=0;}

voidins(heap_te){

for(p=++n;p>1&&_cp(e,h[p>>1]);h[p]=h[p>>1],p>>=1);

h[p]=e;

}

intdel(heap_t&e){

if(!

n)return0;

for(e=h[p=1],c=2;c

h[p]=h[n--];return1;

}

};

voiddijkstra(intn,int*list,edge_t*buf,ints,elem_t*min,int*pre){

heaph;heap_te;

intv[MAXN],i,t,f;

for(i=0;i

min[i]=inf,v[i]=0,pre[i]=-1;

h.init();min[e.v=s]=e.d=0,h.ins(e);

while(h.del(e))

if(!

v[e.v])

for(v[f=e.v]=1,t=list[f];t

if(!

v[buf[t].to]&&min[f]+buf[t].len

pre[buf[t].to]=f,min[e.v=buf[t].to]=e.d=min[f]+buf[t].len,h.ins(e);

}

1.6最短路径(单源dijkstra+mapped_heap邻接表)

//单源最短路径,dijkstra算法+映射二分堆,邻接表形式,复杂度O(mlogn)

//求出源s到所有点的最短路经,传入图的大小n和邻接表list

//返回到各点最短距离min[]和路径pre[],pre[i]记录s到i路径上i的父结点,pre[s]=-1

//可更改路权类型,但必须非负!

#defineMAXN200

#defineinf1000000000

typedefintelem_t;

structedge_t{

intfrom,to;

elem_tlen;

edge_t*next;

};

#define_cp(a,b)((a)<(b))

structheap{

elem_th[MAXN+1];

intind[MAXN+1],map[MAXN+1],n,p,c;

voidinit(){n=0;}

voidins(inti,elem_te){

for(p=++n;p>1&&_cp(e,h[p>>1]);h[map[ind[p]=ind[p>>1]]=p]=h[p>>1],p>>=1);

h[map[ind[p]=i]=p]=e;

}

intdel(inti,elem_t&e){

i=map[i];if(i<1||i>n)return0;

for(e=h[p=i];p>1;h[map[ind[p]=ind[p>>1]]=p]=h[p>>1],p>>=1);

for(c=2;c

h[map[ind[p]=ind[n]]=p]=h[n];n--;return1;

}

intdelmin(int&i,elem_t&e){

if(n<1)return0;i=ind[1];

for(e=h[p=1],c=2;c

h[map[ind[p]=ind[n]]=p]=h[n];n--;return1;

}

};

voiddijkstra(intn,edge_t*list[],ints,elem_t*min,int*pre){

heaph;

edge_t*t;elem_te;

intv[MAXN],i;

for(h.init(),i=0;i

min[i]=((i==s)?

0:

inf),v[i]=0,pre[i]=-1,h.ins(i,min[i]);

while(h.delmin(i,e))

for(v[i]=1,t=list[i];t;t=t->next)

if(!

v[t->to]&&min[i]+t->lento])

pre[t->to]=i,h.del(t->to,e),min[t->to]=e=min[i]+t->len,h.ins(t->to,e);

}

1.7最短路径(单源dijkstra+mapped_heap正向表)

//单源最短路径,dijkstra算法+映射二分堆,正向表形式,复杂度O(mlogn)

//求出源s到所有点的最短路经,传入图的大小n和正向表list,buf

//返回到各点最短距离min[]和路径pre[],pre[i]记录s到i路径上i的父结点,pre[s]=-1

//可更改路权类型,但必须非负!

#defineMAXN200

#defineinf1000000000

typedefintelem_t;

structedge_t{

intto;

elem_tlen;

};

#define_cp(a,b)((a)<(b))

structheap{

elem_th[MAXN+1];

intind[MAXN+1],map[MAXN+1],n,p,c;

voidinit(){n=0;}

voidins(inti,elem_te){

for(p=++n;p>1&&_cp(e,h[p>>1]);h[map[ind[p]=ind[p>>1]]=p]=h[p>>1],p>>=1);

h[map[ind[p]=i]=p]=e;

}

intdel(inti,elem_t&e){

i=map[i];if(i<1||i>n)return0;

for(e=h[p=i];p>1;h[map[ind[p]=ind[p>>1]]=p]=h[p>>1],p>>=1);

for(c=2;c

h[map[ind[p]=ind[n]]=p]=h[n];n--;return1;

}

intdelmin(int&i,elem_t&e){

if(n<1)return0;i=ind[1];

for(e=h[p=1],c=2;c

h[map[ind[p]=ind[n]]=p]=h[n];n--;return1;

}

};

voiddijkstra(intn,int*list,edge_t*buf,ints,elem_t*min,int*pre){

heaph;elem_te;

intv[MAXN],i,t;

for(h.init(),i=0;i

min[i]=((i==s)?

0:

inf),v[i]=0,pre[i]=-1,h.ins(i,min[i]);

while(h.delmin(i,e))

for(v[i]=1,t=list[i];t

if(!

v[buf[t].to]&&min[i]+buf[t].len

pre[buf[t].to]=i,h.del(buf[t].to,e),min[buf[t].to]=e=min[i]+buf[t].len,h.ins(buf[t].to,e);

}

1.8最短路径(单源dijkstra邻接阵)

//单源最短路径,dijkstra算法,邻接阵形式,复杂度O(n^2)

//求出源s到所有点的最短路经,传入图的顶点数n,(有向)邻接矩阵mat

//返回到各点最短距离min[]和路径pre[],pre[i]记录s到i路径上i的父结点,pre[s]=-1

//可更改路权类型,但必须非负!

#defineMAXN200

#defineinf1000000000

typedefintelem_t;

voiddijkstra(intn,elem_tmat[][MAXN],ints,elem_t*min,int*pre){

intv[MAXN],i,j,k;

for(i=0;i

min[i]=inf,v[i]=0,pre[i]=-1;

for(min[s]=0,j=0;j

for(k=-1,i=0;i

if(!

v[i]&&(k==-1||min[i]

k=i;

for(v[k]=1,i=0;i

if(!

v[i]&&min[k]+mat[k][i]

min[i]=min[k]+mat[pre[i]=k][i];

}

}

1.9最短路径(多源floyd_warshall邻接阵)

//多源最短路径,floyd_warshall算法,复杂度O(n^3)

//求出所有点对之间的最短路经,传入图的大小和邻接阵

//返回各点间最短距离min[]和路径pre[],pre[i][j]记录i到j最短路径上j的父结点

//可更改路权类型,路权必须非负!

#defineMAXN200

#defineinf1000000000

typedefintelem_t;

voidfloyd_warshall(intn,elem_tmat[][MAXN],elem_tmin[][MAXN],intpre[][MAXN]){

inti,j,k;

for(i=0;i

for(j=0;j

min[i][j]=mat[i][j],pre[i][j]=(i==j)?

-1:

i;

for(k=0;k

for(i=0;i

for(j=0;j

if(min[i][k]+min[k][j]

min[i][j]=min[i][k]+min[k][j],pre[i][j]=pre[k][j];

}

2、应用

2.1Joseph问题

//Joseph'sProblem

//input:

n,m--thenumberofpersons,theintevalbetweenpersons

//output:

--returnthereferenceoflastperson

intjosephus0(intn,intm)

{

if(n==2)return(m%2)?

2:

1;

intv=(m+josephus0(n-1,m))%n;

if(v==0)v=n;

returnv;

}

intjosephus(intn,intm)

{

if(m==1)returnn;

if(n==1)return1;

if(m>=n)returnjosephus0(n,m);

intl=(n/m)*m;

intj=josephus(n-(n/m),m);

if(j<=n-l)returnl+j;

j-=n-l;

intt=(j/(m-1))*m;

if((j%(m-1))==0)returnt-1;

returnt+(j%(m-1));

}

2.2N皇后构造解

//N皇后构造解,n>=4

voideven1(intn,int*p){

inti;

for(i=1;i<=n/2;i++)

p[i-1]=2*i;

for(i=n/2+1;i<=n;i++)

p[i-1]=2*i-n-1;

}

voideven2(intn,int*p){

inti;

for(i=1;i<=n/2;i++)

p[i-1]=(2*i+n/2-3)%n+1;

for(i=n/2+1;i<=n;i++)

p[i-1]=n-(2*(n-i+1)+n/2-3)%n;

}

voidgenerate(int,int*);

voidodd(intn,int*p){

generate(n-1,p),p[n-1]=n;

}

voidgenerate(intn,int*p){

if(n&1)

odd(n,p);

elseif(n%6!

=2)

even1(n,p);

else

even2(n,p);

}

2.3布尔母函数

//布尔母函数

//判m[]个价值为w[]的货币能否构成value

//适合m[]较大w[]较小的情况

//返回布尔量

//传入货币种数n,个数m[],价值w[]和目标值value

#defineMAXV100000

intgenfunc(intn,int*m,int*w,intvalue){

inti,j,k,c;

charr[MAXV];

for(r[0]=i=1;i<=value;r[i++]=0);

for(i=0;i

for(j=0;j

c=m[i]*r[k=j];

while((k+=w[i])<=value)

if(r[k])

c=m[i];

elseif(c)

r[k]=1,c--;

if(r[value])

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 人文社科 > 哲学历史

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1