【HDU 2544 最短路】
来源:互联网 发布:java网络高级编程 编辑:程序博客网 时间:2024/05/17 08:11
最短路
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条商店到赛场的路线。
Output
对于每组输入,输出一行,表示工作人员从商店走到赛场的最短时间
Sample Input
2 1
1 2 3
3 3
1 2 5
2 3 5
3 1 2
0 0
Sample Output
3
2
附上 floyd , dijkstra 和 spfa邻接表 三种算法 :
floyd :
缺点 :时间复杂度高O(N^3);
优点 : 求出了所有点两两间的最短距离 ;
dijkstra :
缺点 : 只能求出一点到其余各点的最短距离;
优点 : 时间复杂度低O(N^2);
spfa邻接表 :
两点间的关系都可以有临界表处理,时间复杂度较低;
可以处理开不了二维数组的大数据;
根据实际情况,做最佳选择
floyd :
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int INF=0x3f3f3f3f;int mapp[110][110];int N,M;void floyd(){ int i,j,l; for(l=1;l<=N;l++) { for(i=1;i<=N;i++) { if(mapp[i][l]==INF) continue; for(j=1;j<=N;j++) { mapp[i][j]=min(mapp[i][j],mapp[i][l]+mapp[l][j]);//更新 i ,j 两点间的最短距离 } } } printf("%d\n",mapp[1][N]);}int main(){ int i,j; int a,b,c; while(scanf("%d%d",&N,&M)!=EOF) { if(N==0&&M==0) break; for(i=1;i<=N;i++) { mapp[i][i]=0; for(j=1;j<i;j++) mapp[i][j]=mapp[j][i]=INF; } while(M--) { scanf("%d%d%d",&a,&b,&c); if(mapp[a][b]>c)//判断是否有重边 mapp[a][b]=mapp[b][a]=c; } floyd(); } return 0;}
dijkstra :
#include<cstdio>#include<cstring>const int INF=0x3f3f3f3f;int mapp[110][110];int vis[110];//标记点int dis[110];int N,M;void dijkstra(){ int i,j; int ml; int ans;//记录最小距离 memset(vis,0,sizeof(vis));//初始化标记 for(i=1;i<=N;i++) dis[i]=mapp[1][i];//当前所有的点到商店的最短距离 vis[1]=1;//标记 1 点 for(i=2;i<=N;i++) { ans=INF; for(j=1;j<=N;j++) { if(vis[j]==0&&ans>dis[j]) { ans=dis[j];//记录小到 i 点的最短距离 ml=j;//记录小到 i 点的距离最短的点 } } vis[ml]=1;//把该点标记 for(j=1;j<=N;j++) { if(vis[j]==0&&dis[ml]+mapp[ml][j]<dis[j]) dis[j]=dis[ml]+mapp[ml][j];//更新到 1 点的最短距离 } } printf("%d\n",dis[N]);//输出赛场到商店的最短距离}int main(){ int i,j; int a,b,c; while(scanf("%d%d",&N,&M)!=EOF) { if(N==0&&M==0) break; for(i=1;i<=N;i++) { mapp[i][i]=0; for(j=1;j<i;j++) mapp[i][j]=mapp[j][i]=INF; } for(i=1;i<=M;i++) { scanf("%d%d%d",&a,&b,&c); if(mapp[a][b]>c)//建议养成习惯加上可能会有重边的的情况 mapp[a][b]=mapp[b][a]=c; } dijkstra(); } return 0;}
spfa邻接表 :
#include<cstdio>#include<algorithm>#include<queue>#include<cstring>using namespace std;const int INF=0x3f3f3f3f;struct node{ int to,val,next;}st[10011];int head[110];int dis[110];int vis[110];int num;int N,M;void init()//初始化{ num=0; memset(head,-1,sizeof(head)); memset(vis,0,sizeof(vis));}void add(int x,int y,int z){ st[num].to=y; st[num].val=z; st[num].next=head[x]; head[x]=num++;}/*void add(int x,int y,int z)//同上面的效果一样,两种临界表的建立方式{ node E={y,z,head[x]}; st[num]=E; head[x]=num++;}*/void spfa(){ queue <int> q; while(!q.empty()) q.pop(); int i,j; fill(dis+1,dis+N+1,INF); dis[1]=0; q.push(1); vis[1]=1;//标记 while(!q.empty()) { int w=q.front(); q.pop(); vis[w]=0;//释放 for(i=head[w];i!=-1;i=st[i].next) { int ml=st[i].to;//遍历以 w 为起点的所有边的终点 ml if(dis[ml]>dis[w]+st[i].val) { dis[ml]=dis[w]+st[i].val; if(!vis[ml])//优化 不会有多余的点进队列 { vis[ml]=1; q.push(ml); } } } } printf("%d\n",dis[N]);//1到N的最短距离}int main(){ int a,b,c; while(scanf("%d%d",&N,&M)!=EOF) { if(N==0&&M==0) break; init(); while(M--) { scanf("%d%d%d",&a,&b,&c); add(a,b,c);//建立临界表 add(b,a,c); } spfa(); } return 0;}
0 0
- 最短路 2544hdu
- HDU 2544 最短路
- HDU-2544 最短路
- Hdu-2544 最短路
- HDU 2544 最短路
- hdu 2544 最短路
- HDU 2544 ( 最短路 )
- hdu 2544 最短路
- HDU 2544 最短路
- hdu 2544 最短路
- hdu 2544 最短路
- HDU 2544 最短路
- hdu 2544 最短路
- HDU 2544 最短路
- hdu 2544 最短路
- HDU 2544 最短路
- hdu 2544 最短路
- hdu 2544 最短路
- window下python无法安装lxml问题解决
- iOS判断 英文 数字 汉字等
- HDU 2710 Max Factor
- 知乎上遇到的对AOP的理解
- 转一篇心灵鸡汤,在贴吧上看的,作者不详
- 【HDU 2544 最短路】
- Cocos2d-x的学习 触碰事件老版本和新版本的对比 第四节
- 【HDU 5283】【JZOJ 4694】 火神的鱼
- 顺序栈和链式栈的理解与使用
- 【转】脉络清晰的BP神经网络讲解
- Java基础增强---枚举
- iOS 数据存储:Plist
- 链式存储结构即链式结构简单介绍
- BZOJ2160 拉拉队排练