HDOJ 2544 最短路(四种做法)
2016-06-20 21:49
423 查看
DFS(因为是求总时间,只需将简单的深搜求最短路的方法,二维数组清零即可):
原始的DFS:
修改后的DFS:
Dijkstra:
Floyd:
原始的DFS:
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int INF=99999999;//正无穷 int minn; int n,e[105][105],book[105]; void dfs(int cur,int dis) { int j; //已经超过前面查找的最短路径,就不需要在查找了 if(dis>minn) return; if(cur==n)//到达了 { minn=min(dis,minn); return; } for(j=1;j<=n;j++)//从1号城市到n号城市依次尝试 {//判断当前城市cur到城市j是否有路,并判断城市j是否已经走过 if(e[cur][j]!=INF&&book[j]==0) { book[j]=1;//标记已经走过 dfs(j,dis+e[cur][j]);//从城市j再出发,继续寻找 book[j]=0; } } return; } int main() { int i,j,m,a,b,c; while(~scanf("%d%d",&n,&m)&&(n||m)) { //初始化二维矩阵 memset(book,0,sizeof(book)); for(i=1;i<=n;i++) for(j=1;j<=n;j++) if(i==j) e[i][j]=0;//自己 else e[i][j]=INF; //读入城市之间的距离 for(i=1;i<=m;i++) { scanf("%d%d%d",&a,&b,&c); e[a][b]=c; e[b][a]=c; } minn=INF; //从1号城市出发 book[1]=1; dfs(1,0); printf("%d\n",minn); } return 0; } /* 5 8//五个城市,10条路径 1 2 2 1 5 10 2 3 3 2 5 7 3 1 4 3 4 4 4 5 5 5 3 3 */
修改后的DFS:
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int INF = 999999; int minn; int n,m,e[105][105],book[105]; void dfs(int cur,int dis) { int j; if(dis>minn) return; if(cur==n)//到达了终点 { minn=dis; return; } for(int i=2;i<=n;i++) { if(e[cur][i]&&!book[i]) { book[i]=1; dfs(i,dis+e[cur][i]); book[i]=0;//回溯 } } return; } int main() { while(~scanf("%d%d",&n,&m)&&(n||m)) { memset(e,0,sizeof(e)); memset(book,0,sizeof(book)); int a,b,c; for(int i=1;i<=m;i++) { scanf("%d%d%d",&a,&b,&c); e[a][b]=c; e[b][a]=c; } //book[1]=1; minn=INF; dfs(1,0); printf("%d\n",minn); } return 0; }
Dijkstra:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int INF = 99999999; int main() { int e[105][105],dis[105],book[105]; int n,m; while(~scanf("%d%d",&n,&m)&&(n||m)) { for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(i==j) e[i][j]=0; else e[i][j]=INF; int t1,t2,t3; for(int i=1;i<=m;i++) { scanf("%d%d%d",&t1,&t2,&t3); e[t1][t2]=t3;//双向边 e[t2][t1]=t3; } //初始化dis数组,哲理是1号顶点到其余各顶点的初始路程 for(int i=1;i<=n;i++) dis[i]=e[1][i]; memset(book,0,sizeof(book));//初始化 book[1]=0;//因为1点是源点 int minn,u,v; //Dijkstra算法核心语句 for(int i=1;i<=n-1;i++)//n-1 { //找到离1号顶点最近的顶点 //是每次都要找 minn=INF; for(int j=1;j<=n;j++) { if(book[j]==0&&dis[j]<minn) { minn=dis[j]; u=j; } } book[u]=1;//一个新的起点 for(v=1;v<=n;v++) { if(e[u][v]<INF) { if(dis[v]>dis[u]+e[u][v]) dis[v]=dis[u]+e[u][v]; } } } //输出 printf("%d\n",dis ); } return 0; } /* 6 9 1 2 1 1 3 12 2 3 9 2 4 3 3 5 5 4 3 4 4 5 13 4 6 15 5 6 4 */
Floyd:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int INF = 99999999; int main() { int e[105][105],dis[105],book[105]; int n,m; while(~scanf("%d%d",&n,&m)&&(n||m)) { for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(i==j) e[i][j]=0; else e[i][j]=INF; int t1,t2,t3; for(int i=1;i<=m;i++) { scanf("%d%d%d",&t1,&t2,&t3); e[t1][t2]=t3;//双向边 e[t2][t1]=t3; } memset(book,0,sizeof(book));//初始化 for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(e[i][j]>e[i][k]+e[k][j]) e[i][j]=e[i][k]+e[k][j]; printf("%d\n",e[1] ); } return 0; } /* 6 9 1 2 1 1 3 12 2 3 9 2 4 3 3 5 5 4 3 4 4 5 13 4 6 15 5 6 4 */
相关文章推荐
- 什么是Intent(意图)
- Poj 2226 Muddy Fields【二分匹配】
- 关于软件开发团队的一些思考
- 【c++程序】不同字符的个数统计
- javascript之DOM操作
- 55. Jump Game
- libvlc 打开较大MP4文件,关闭慢的问题.
- ubuntu samba服务器的安装和出错修改
- 把自己的开源库添加cocoapods
- jsp前台中关于c标签的一些使用(c:choose和c:forEach)
- 获取操作系统版本的几种方法
- 二维数组中的查找
- caffe基础(2):视觉层及参数
- 【剑指offer】树的子结构
- 信号(signal)介绍
- JavaSE学习56:GUI编程之事件模型(一)
- 双链播放寻址
- hdu 1521 排列组合 指数型母函数
- leetcode 203 Remove-Linked-List-Elements
- 计算阶乘的另一些有趣的算法(转载)