第十六周:( Sicily1321) Robot(c++)
来源:互联网 发布:淘宝上的内存条能买吗 编辑:程序博客网 时间:2024/06/05 10:32
原题链接:
http://soj.sysu.edu.cn/1321
思路:这是一道求单源最短路的题,笔者分别用Dijkstra和Bellman-Ford两种算法求解。我们知道,Dijkstra算法对只含有正权边的图管用,一般情况下(不用二分堆)复杂度是O(V^2)。而BellmanFord算法对含有负权边的图一样管用,其复杂度为O(V*E),但如果图是稀疏图,此算法的效率更好!以下代码,Bellman-Ford算法的ac时间为0.03s,Dijkstra的ac时间为0.37s,这应该也是因为图比较稀疏的原因。
代码一(Dijkstra算法):
#include <iostream>using namespace std;#define INF 999999999int Matrix[105][105],DisMatrix[105][105];bool Visited[105][105];int Dijkstra(pair<int,int> start,pair<int,int> end, int m, int n){ pair<int,int> MinDistancePoint; int nPoint=m*n; //初始化 Visited[start.first][start.second]=true; DisMatrix[start.first][start.second]=Matrix[start.first][start.second]; MinDistancePoint=start; for(int i=1;i<nPoint;i++){ int x=MinDistancePoint.first,y=MinDistancePoint.second; //更新到start点的值 if((x-1>=1)&&(!Visited[x-1][y])&&((DisMatrix[x][y]+Matrix[x-1][y])<DisMatrix[x-1][y])) DisMatrix[x-1][y]=DisMatrix[x][y]+Matrix[x-1][y]; if((y-1>=1)&&(!Visited[x][y-1])&&((DisMatrix[x][y]+Matrix[x][y-1])<DisMatrix[x][y-1])) DisMatrix[x][y-1]=DisMatrix[x][y]+Matrix[x][y-1]; if((x+1<=m)&&(!Visited[x+1][y])&&((DisMatrix[x][y]+Matrix[x+1][y])<DisMatrix[x+1][y])) DisMatrix[x+1][y]=DisMatrix[x][y]+Matrix[x+1][y]; if((y+1<=n)&&(!Visited[x][y+1])&&((DisMatrix[x][y]+Matrix[x][y+1])<DisMatrix[x][y+1])) DisMatrix[x][y+1]=DisMatrix[x][y]+Matrix[x][y+1]; int MinDistance=INF; //查找下一个visited的点(即未visited中最近的点) for(int a=1;a<=m;a++) for(int b=1;b<=n;b++){ if((!Visited[a][b])&&(DisMatrix[a][b]<MinDistance)){ MinDistance=DisMatrix[a][b]; MinDistancePoint.first=a; MinDistancePoint.second=b; } } //访问最小的点 Visited[MinDistancePoint.first][MinDistancePoint.second]=true; } return DisMatrix[end.first][end.second];}int main(){ int T; cin>>T; while(T--){ int m,n; cin>>m>>n; if((m==0)||(n==0)) cout<<0<<endl; for(int i=1;i<=m;i++) for(int j=1;j<=n;j++){ cin>>Matrix[i][j]; DisMatrix[i][j]=INF; Visited[i][j]=false; } pair<int,int> start,end; cin>>start.first>>start.second>>end.first>>end.second; cout<<Dijkstra(start,end,m,n)<<endl; } return 0;}
代码二(Bellman-Ford算法):
#include <iostream>#include <queue>using namespace std;#define INF 999999999int Matrix[105][105],DisMatrix[105][105];int BellmanFord(pair<int,int> start,pair<int,int> end, int m, int n){ queue <pair<int,int>> UpdatePoint; int nPoint=m*n; //初始化 DisMatrix[start.first][start.second]=Matrix[start.first][start.second]; UpdatePoint.push(start); for(int i=1;i<nPoint;i++){ queue <pair<int,int>> NextUpdatePoint; //更新 while(!UpdatePoint.empty()){ pair<int,int> point; point=UpdatePoint.front(); int x=point.first; int y=point.second; if((x-1>=1)&&((DisMatrix[x][y]+Matrix[x-1][y])<DisMatrix[x-1][y])){ DisMatrix[x-1][y]=DisMatrix[x][y]+Matrix[x-1][y]; NextUpdatePoint.push(make_pair(x-1,y)); } if((y-1>=1)&&((DisMatrix[x][y]+Matrix[x][y-1])<DisMatrix[x][y-1])){ DisMatrix[x][y-1]=DisMatrix[x][y]+Matrix[x][y-1]; NextUpdatePoint.push(make_pair(x,y-1)); } if((x+1<=m)&&((DisMatrix[x][y]+Matrix[x+1][y])<DisMatrix[x+1][y])){ DisMatrix[x+1][y]=DisMatrix[x][y]+Matrix[x+1][y]; NextUpdatePoint.push(make_pair(x+1,y)); } if((y+1<=n)&&((DisMatrix[x][y]+Matrix[x][y+1])<DisMatrix[x][y+1])){ DisMatrix[x][y+1]=DisMatrix[x][y]+Matrix[x][y+1]; NextUpdatePoint.push(make_pair(x,y+1)); } UpdatePoint.pop(); } //更新下轮需要更新的点 while(!NextUpdatePoint.empty()){ UpdatePoint.push(NextUpdatePoint.front()); NextUpdatePoint.pop(); } } return DisMatrix[end.first][end.second];}int main(){ int T; cin>>T; while(T--){ int m,n; cin>>m>>n; if((m==0)||(n==0)) cout<<0<<endl; for(int i=1;i<=m;i++) for(int j=1;j<=n;j++){ cin>>Matrix[i][j]; DisMatrix[i][j]=INF; } pair<int,int> start,end; cin>>start.first>>start.second>>end.first>>end.second; cout<<BellmanFord(start,end,m,n)<<endl; } return 0;}
阅读全文
1 0
- 第十六周:( Sicily1321) Robot(c++)
- sicily1321. Robot
- sicily1321. Robot
- sicily1321-robot
- 第十六周:[Sicily]1321. Robot
- 第十六周OJ(C)
- C. Robot(BFS)
- 第十六周:C语言:坐标
- 第十六周OJ(C)——有相同数字 !
- 第十六周—C语言(字符串的插入)
- 第十六周—C语言 (字符串的替换)
- 第十六周—C语言 (字符串分段)
- 第十六周—C语言 (猴子分桃)
- 第十六周:( LeetCode606) Construct String from Binary Tree(c++)
- 第十六周:(Sicily) Huffman Coding V1(c++)
- 第十六周 问题 C: 相同的数字!
- 第十六周 Problem C:相同的数字
- 第十六周项目一 c阅读程序
- Android.mk的一些FAQ
- AOP的简单应用
- 程序员——高考的第二春
- FreeMarker
- 关于Android6.0 权限 文件读写
- 第十六周:( Sicily1321) Robot(c++)
- R-CNN,Fast R-CNN,Faster R-CNN
- git实现代码提交自动部署到相应的web服务器
- Java实现-不同的路径2
- 前端与后端的关系
- 几种代码量统计工具的安装及使用
- 056、057、058-C++
- [RK3288][Android6.0] 调试笔记 --- Audio的Voice Call无法静音问题
- VC++ 取得 其他app的ListBox 内容