图论.docx
- 文档编号:8226397
- 上传时间:2023-01-30
- 格式:DOCX
- 页数:14
- 大小:51.27KB
图论.docx
《图论.docx》由会员分享,可在线阅读,更多相关《图论.docx(14页珍藏版)》请在冰豆网上搜索。
图论
(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; } (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]; } (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]; } (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->len pre[t->to]=t->from,min[e.v=t->to]=e.d=min[t->from]+t->len,h.ins(e); } (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); } (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->len pre[t->to]=i,h.del(t->to,e),min[t->to]=e=min[i]+t->len,h.ins(t->to,e); } (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); } (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]; } } (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]; } //无向图连通分支,bfs邻接阵形式,O(n^2) //返回分支数,id返回1..分支数的值 //传入图的大小n和邻接阵mat,不相邻点边权0 #defineMAXN100 intfind_components(intn,intmat[][MAXN],int*id){ intret,k,i,j,m; for(k=0;k for(ret=k=0;k if(! id[k]) for(id[k]=-1,ret++,m=1;m;) for(m=i=0;i if(id[i]==-1) for(m++,id[i]=ret,j=0;j if(! id[j]&&mat[i][j]) id[j]=-1; returnret; } //无向图连通分支,dfs邻接阵形式,O(n^2) //返回分支数,id返回1..分支数的值 //传入图的大小n和邻接阵mat,不相邻点边权0 #defineMAXN100 voidfloodfill(intn,intmat[][MAXN],int*id,intnow,inttag){ inti; for(id[now]=tag,i=0;i if(! id[i]&&mat[now][i]) floodfill(n,mat,id,i,tag); } intfind_components(intn,intmat[][MAXN],int*id){ intret,i; for(i=0;i for(ret=i=0;i if(! id[i]) floodfill(n,mat,id,i,++ret); returnret; } //有向图强连通分支,bfs邻接阵形式,O(n^2) //返回分支数,id返回1..分支数的值 //传入图的大小n和邻接阵mat,不相邻点边权0 #defineMAXN100 intfind_components(intn,intmat[][MAXN],int*id){ intret=0,a[MAXN],b[MAXN],c[MAXN],d[MAXN],i,j,k,t; for(k=0;k for(k=0;k if(! id[k]){ for(i=0;i a[i]=b[i]=c[i]=d[i]=0; a[k]=b[k]=1; for(t=1;t;) for(t=i=0;i if(a[i]&&! c[i]) for(c[i]=t=1,j=0;j if(mat[i][j]&&! a[j]) a[j]=1; if(b[i]&&! d[i]) for(d[i]=t=1,j=0;j if(mat[j][i]&&! b[j]) b[j]=1; } for(ret++,i=0;i if(a[i]&b[i]) id[i]=ret; } returnret;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 图论