图-最短路径问题- Floyd
来源:互联网 发布:php抽奖概率算法 编辑:程序博客网 时间:2024/05/19 05:04
POJ5443兔子与樱花
总时间限制: 1000ms 内存限制: 65535kB
描述
很久很久之前,森林里住着一群兔子。有一天,兔子们希望去赏樱花,但当他们到了上野公园门口却忘记了带地图。现在兔子们想求助于你来帮他们找到公园里的最短路。输入
输入分为三个部分。
第一个部分有P+1行(P<30),第一行为一个整数P,之后的P行表示上野公园的地点。
第二个部分有Q+1行(Q<50),第一行为一个整数Q,之后的Q行每行分别为两个字符串与一个整数,表示这两点有直线的道路,并显示二者之间的矩离(单位为米)。
第三个部分有R+1行(R<20),第一行为一个整数R,之后的R行每行为两个字符串,表示需要求的路线。
输出
输出有R行,分别表示每个路线最短的走法。其中两个点之间,用->(矩离)->相隔。
样例输入
6
Ginza
Sensouji
Shinjukugyoen
Uenokouen
Yoyogikouen
Meijishinguu
6
Ginza Sensouji 80
Shinjukugyoen Sensouji 40
Ginza Uenokouen 35
Uenokouen Shinjukugyoen 85
Sensouji Meijishinguu 60
Meijishinguu Yoyogikouen 35
2
Uenokouen Yoyogikouen
Meijishinguu Meijishinguu
样例输出
Uenokouen->(35)->Ginza->(80)->Sensouji->(60)->Meijishinguu->(35)->Yoyogikouen
Meijishinguu
思路分析:
显然,这又是一道求每队顶点间最短路的问题。我们观察总共的顶点数目较少,O(n^3)的复杂度是可以接受的。所以我们考虑用Floyd算法。事实上这道题的算法实现时很简单的,但我们要注意如何把实现过程处理得尽量漂亮不容易出错。
细节处理上的小技巧
- 利用map 来形成名称和位置序号的一一映射
map<string, int>Index;for (int i = 1; i <= P; i++){ cin >> s; Index[s] = i; }
STL关联容器 map的相关介绍
- 定义
map<int, string> mapS;
- 数据插入
mapStudent.insert(pair<int, string>(1, "s_one")); mapStudent[3] = "s_three";//可以覆盖以前关键字对应的值
- map的大小
int nSize = mapS.size();
- map的遍历
for(iter = mapS.begin(); iter != mapS.end(); iter++) { cout<<iter->first<<" "<<iter->second<<endl; } //前向迭代器for(iter = mapS.rbegin(); iter != mapS.rend(); iter++) { cout<<iter->first<<" "<<iter->second<<endl; } //反向迭代器for(int nIndex = 0; nIndex < nSize; nIndex++) { cout<<mapS[nIndex]<<end; } //数组
- 数据的查找
iter = mapS.find(1);
floyd算法
void Floyd(){ for (int k = 1; k <= P; k++)//第k次迭代 for (int i = 1; i <= P; i++) if (i != k) for (int j = 1; j <= P; j++) if (j != k && f[i][k] + f[k][j] < f[i][j]) //如果从i到j的路径上经过了k同时经过k的那条路径比原来的路径短 { f[i][j] = f[i][k] + f[k][j];//更新路径长度 g[i][j] = g[i][k];//i到j路径上i的后继 }}
- 注意维护从i到j路径上的后继节点
初始化过程
scanf("%d", &P); for (int i = 1; i <= P; i++) { cin >> s; Index[s] = i; Name[i] = s; } for (int i = 1; i <= P; i++) for (int j = 1; j <= P; j++) f[i][j] = INF; for (int i = 1; i <= P; i++) f[i][i] = 0; for (int i = 1; i <= Q; i++) { int d; cin >> s >> t; scanf("%d", &d); int u = Index[s], v = Index[t]; if (d < f[u][v]) f[u][v] = f[v][u] = d; //注意一下万一有重复输入 g[u][v] = v; g[v][u] = u; //注意一下无向图 }
注意点:
1.map容器的插入
2.注意是无向图
3.注意处理重复输入等特殊情况
Query过程
scanf("%d", &R); for (int i = 1; i <= R; i++) { cin >> s >> t; int u = Index[s], v = Index[t]; Query(u, v); }
void Query(int u, int v)//访问u{ for (int w = u; w != v; w = g[w][v]) { cout << Name[w] << "->(" << f[w][g[w][v]] << ")->"; } cout << Name[v] << endl;}
POJ9200社交网络
#include <iostream>using namespace std;int N;const int MaxN = 305;int M[MaxN][MaxN];void Floyd(){ for(int k = 1; k <= N; k++) for(int i = 1; i <= N; i++) for(int j = 1; j <= N; j++) if(M[i][k] == 1 && M[k][j] == 1) M[i][j] = 1;}int main(){#ifndef ONLINE_JUDGE freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);#endif scanf("%d", &N); cin.get(); for(int i = 1; i <= N; i++) { for(int j = 1; j <= N; j++) { M[i][j] = cin.get()-'0'; //printf("%d ",M[i][j]); } //printf("\n"); cin.get(); } Floyd(); for(int i = 1; i <= N; i++) { for(int j = 1; j <= N; j++) { printf("%d",M[i][j]); } printf("\n"); }#ifndef ONLINE_JUDGE fclose(stdin); fclose(stdout);#endif return 0;}
简单Floyd 注意点 输入数据的时候的cin.get()应用
- 图-最短路径问题- Floyd
- Floyd(最短路径问题)
- Floyd算法解决最短路径问题
- 最短路径问题---Floyd算法详解
- 最短路径问题(Floyd算法)
- 【Floyd】[CODEVS] p2602 最短路径问题
- 数据结构 最短路径问题 Floyd算法
- 最短路径问题(Floyd算法)
- 最短路径问题(floyd算法)
- 最短路径问题---Floyd算法详解
- Floyd 最短路径
- Floyd最短路径
- 最短路径Floyd
- 最短路径---Floyd
- 图结构 最短路径 Floyd算法
- 图之 最短路径 Floyd算法
- 图-最短路径-Floyd算法
- 最短路径问题--Floyd多源最短路径算法
- PendingIntent
- 关于最大传输单元(MTU)的整理
- Android 保存图片到手机相册
- 如何将 oracle 和 mysql数据库的相互迁移
- MySQL查询优化:LIMIT 1避免全表扫描
- 图-最短路径问题- Floyd
- Intent及其七大属性及intent-filter设置
- java 8 分组
- linux awk命令详解
- Tomcat 系统架构与设计模式,第 2 部分
- Spring Boot之自动配置的原理
- 移动APP测试用例设计实践经验分享
- mysql--索引优化
- python2.7安装mysql驱动