hdu 2544 最短路(最短路径)(flody、dij、dij+priority queue、bellman、spfa)
来源:互联网 发布:企业淘宝开店流程 编辑:程序博客网 时间:2024/05/22 04:27
最短路
Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 20581 Accepted Submission(s): 8811
Problem Description
在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt。但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗?
Input
输入包括多组数据。每组数据第一行是两个整数N、M(N<=100,M<=10000),N表示成都的大街上有几个路口,标号为1的路口是商店所在地,标号为N的路口是赛场所在地,M则表示在成都有几条路。N=M=0表示输入结束。接下来M行,每行包括3个整数A,B,C(1<=A,B<=N,1<=C<=1000),表示在路口A与路口B之间有一条路,我们的工作人员需要C分钟的时间走过这条路。
输入保证至少存在1条商店到赛场的路线。
输入保证至少存在1条商店到赛场的路线。
Output
对于每组输入,输出一行,表示工作人员从商店走到赛场的最短时间
Sample Input
2 11 2 33 31 2 52 3 53 1 20 0
Sample Output
32
Source
UESTC 6th Programming Contest Online
Recommend
lcy
题解:最短路径....下面给出部分最短路径解法以作总结(flody、dij、dij+priority queue、bellman、spfa)
flody算法:邻接矩阵存图,用3重for循环对枚3个点,以2条路径不断构成1条更短的路径
//flody算法#include<stdio.h>#include<string.h>#define INF 1<<29int c[105][105],n;void init(){ int i,j; for(i=0;i<=n;i++) for(j=0;j<=n;j++) c[i][j]=i==j?0:INF;}void flody(){ int i,j,k; for(k=1;k<=n;k++) for(i=1;i<=n;i++) for(j=1;j<=n;j++) if(c[i][j]>c[i][k]+c[k][j]) c[i][j]=c[i][k]+c[k][j];}int main(){ int x,y,z,m,i; while(scanf("%d%d",&n,&m)>0) { if(n==0&&m==0) break; init(); for(i=0;i<m;i++) { scanf("%d%d%d",&x,&y,&z); c[x][y]=c[y][x]=z; } flody(); printf("%d\n",c[1][n]); } return 0;}
裸dij算法:邻接矩阵or邻接表存图,每次提取出未更新过且距离起点最近的点,标记该点,并通过该点更新其他点到起点的距离,每一个点只更新一次,一共更新n次
//裸dij算法#include<stdio.h>#include<string.h>#define INF 1<<28int c[105][105],l[105],mark[105],n;void init(){ int i,j; for(i=0;i<=n;i++) for(j=0;j<=n;j++) c[i][j]=INF; for(l[1]=0,i=2;i<=n;i++) l[i]=INF; memset(mark,0,sizeof(mark));}void dij(){ int i,j,m,make; for(i=0;i<n;i++) { for(m=INF,j=1;j<=n;j++) { if(!mark[j]&&l[j]<m) make=j,m=l[j]; } mark[make]=1; for(j=1;j<=n;j++) { if(!mark[j]&&c[make][j]<INF&&l[j]>l[make]+c[make][j]) l[j]=l[make]+c[make][j]; } }}int main(){ int x,y,z,m,i; while(scanf("%d%d",&n,&m)>0) { if(n==0&&m==0) break; init(); for(i=0;i<m;i++) { scanf("%d%d%d",&x,&y,&z); c[x][y]=c[y][x]=z; } dij(); printf("%d\n",l[n]); } return 0;}
dij+priority queue优化:邻接矩阵or邻接表存图,在提取未更新过且最近的点的时候利用优先队列来提取,标记该点,且对每个可进行更新的点入队,这个点必定未更新过,直到优先队列为空则停止更新
//优先队列dij#include<stdio.h>#include<string.h>#include<queue>#define INF 1<<28using namespace std;struct point{ int id,dis;}cc;bool operator <(const point &a,const point &b){ return b.dis<a.dis;}priority_queue<point>q;int c[105][105],l[105],mark[105],n;void init(){ int i,j; for(i=0;i<=n;i++) for(j=0;j<=n;j++) c[i][j]=INF; for(l[1]=0,i=2;i<=n;i++) l[i]=INF; memset(mark,0,sizeof(mark));}void dij(){ int i,x; cc.id=1,cc.dis=0; q.push(cc); while(!q.empty()) { cc=q.top(); q.pop(); x=cc.id; mark[x]=1; for(i=1;i<=n;i++) { if(!mark[i]&&l[i]>l[x]+c[i][x]) { l[i]=l[x]+c[i][x]; cc.id=i,cc.dis=l[i]; q.push(cc); } } }}int main(){ int x,y,z,m,i; while(scanf("%d%d",&n,&m)>0) { if(n==0&&m==0) break; init(); for(i=0;i<m;i++) { scanf("%d%d%d",&x,&y,&z); c[x][y]=c[y][x]=z; } dij(); printf("%d\n",l[n]); } return 0;}
bellman:可以计算有负权,用普通的结构体将所有边存起来。对所有的边进行n-1次松弛更新点的最短距离,若某一次松弛已经不能更新,则可以退出循环,若n-1次更新后仍然能继续更新,则存在负权。
//bellman算法#include<stdio.h>#include<string.h>#define INF 1<<28int p[105],n;int dis[105],cou;struct edge{ int x,y,l;}v[20005];void init(){ int i=2; for(;i<=n;i++) dis[i]=INF; cou=dis[1]=0;}void add(int x,int y,int z){ v[cou].x=x; v[cou].y=y; v[cou++].l=z;}void bellman(){ int flag=1,i,j; for(j=0;j<n-1&&flag;j++) { flag=0; for(i=0;i<cou;i++) { if(dis[v[i].x]+v[i].l<dis[v[i].y]) { flag=1; dis[v[i].y]=dis[v[i].x]+v[i].l; } } }}int main(){ int m,i,x,y,z; while(scanf("%d%d",&n,&m)>0) { if(n==0&&m==0) break; init(); for(i=0;i<m;i++) { scanf("%d%d%d",&x,&y,&z); add(x,y,z); add(y,x,z); } bellman(); printf("%d\n",dis[n]); }}
spfa算法:可计算负权,由于一般不用该算法处理稠密图,所以一般用邻接表存图。由起点入队开始,每一次从队列出一个点,由该点出发更新其他点,对于每一个被更新且未入队的点都使其进入队列,每一个点可多次入队但不可以同时出现在队列2次,直到队列为空。
//spfa算法#include<stdio.h>#include<string.h>#define INF 1<<28int p[105],inse,n;int dis[105],que[20005],mark[105];struct linjiebiao{ int data,l,next;}v[10005];void init(){ int i; for(i=0;i<=n;i++) { p[i]=-1; dis[i]=INF; mark[i]=0; } dis[1]=0;}void add(int x,int y,int z){ v[inse].next=p[x]; v[inse].data=y; v[inse].l=z; p[x]=inse++;}void spfa(){ int sta=0,fin=1,temp,x; que[0]=mark[0]=1; while(sta<fin) { x=que[sta++]; mark[x]=0; temp=p[x]; while(temp!=-1) { if(dis[v[temp].data]>dis[x]+v[temp].l) { dis[v[temp].data]=dis[x]+v[temp].l; if(!mark[v[temp].data]) { que[fin++]=v[temp].data; mark[v[temp].data]=1; } } temp=v[temp].next; } }}int main(){ int m,i,x,y,z; while(scanf("%d%d",&n,&m)>0) { if(n==0&&m==0) break; init(); for(inse=i=0;i<m;i++) { scanf("%d%d%d",&x,&y,&z); add(x,y,z),add(y,x,z); } spfa(); printf("%d\n",dis[n]); }}
- hdu 2544 最短路(最短路径)(flody、dij、dij+priority queue、bellman、spfa)
- 【HDU 2544】最短路(dij)
- 【HDU 2544】最短路(Dij)
- 1088: 最短路(SPFA算法 &dij)
- 最短路模板(dij+spfa)
- hdu 2544 最短路 (dij)
- HDU 2544 最短路 Dij
- HDU 3790 最短路径问题 dij
- 最短路模板合集~(Dij+Floyd+Spfa)
- HDU2544-最短路(dij堆优化与spfa)
- hd 2544 最短路径(简单dij)
- Dij.......最短路径算法
- DIJ问题,最短路径
- dij 最短路径模板
- 1089: 道路重建(dij 最短路径)
- HDU 1546 Idiomatic Phrases Game(最短路径)DIJ算法
- 【POJ 2502】Subway(最短路dij)
- HDOJ 2544 最短路(DIJ+优先队列)
- Boost.Interprocess使用指南(1)
- 记事本
- Python list 增加/插入元素的说明
- linux中likely与unlikely
- Avoid Texture Aliasing and Mipmapping
- hdu 2544 最短路(最短路径)(flody、dij、dij+priority queue、bellman、spfa)
- Java_1
- 从程序员到CTO的Java技术路线图
- hdu 1561 The more, The Better(树形背包)
- netcat获得反向shell
- 《卡特教练》观后感
- css3做了一个卷轴样式的菜单
- SQL触发器实例讲解
- 补码-自己的理解