URAL1004 Sightseeing Trip Floyd 最小环
2015-12-14 05:43
411 查看
题意:求有权无向图的最小环,环至少包括三个点。
思路:
设map[i,j]表示i到j的的距离。输入有重边,在处理输入的时候只保存最短边。
取环中一个点k,左右点是ij则map[i,k]和map[k,j]是固定的不能变,可改变的是没有加入k点的i,j之间的最短路,设为dist[i,j]。那么最短环的长度表示为dist[i,j]+map[i,k]+map[k,j]。
Floyd的最外层循环为k时,最短路还没有用k和更新ij之间的最短路,恰好符合要求。所以在还没有用k更新ij之间的最短路之前更新环,每次更新环时更新路径即可。
算法步骤:
输入输出Floyd算法的框架,三个循环,在更新路径前更新环的最短路径。题解一和其他的题解(都是DP)代码很短,步骤很清晰,所以算法步骤粗略写写。
算法复杂度:
输入输出两个循环不超过O(n2),时间主要消耗在Floyd算法的框架里,三个n次循环,所以时间复杂度O(n3),最多是二维数组,空间复杂度是O(n2)
代码:
思路:
设map[i,j]表示i到j的的距离。输入有重边,在处理输入的时候只保存最短边。
取环中一个点k,左右点是ij则map[i,k]和map[k,j]是固定的不能变,可改变的是没有加入k点的i,j之间的最短路,设为dist[i,j]。那么最短环的长度表示为dist[i,j]+map[i,k]+map[k,j]。
Floyd的最外层循环为k时,最短路还没有用k和更新ij之间的最短路,恰好符合要求。所以在还没有用k更新ij之间的最短路之前更新环,每次更新环时更新路径即可。
算法步骤:
输入输出Floyd算法的框架,三个循环,在更新路径前更新环的最短路径。题解一和其他的题解(都是DP)代码很短,步骤很清晰,所以算法步骤粗略写写。
算法复杂度:
输入输出两个循环不超过O(n2),时间主要消耗在Floyd算法的框架里,三个n次循环,所以时间复杂度O(n3),最多是二维数组,空间复杂度是O(n2)
代码:
const int maxn=110; int dist[maxn][maxn], map[maxn][maxn]; //最短距离,原图 int pre[maxn][maxn]; // pre[i,j]记录最短路里,j前面一个点 int path[maxn]; // 答案路径 int n, m, num, minc; // num记录path里有多少个点,minc是最短环长度 int main() { int u, v, cost; while(cin >> n && n){ if(n<0) break; cin >> m; for(int i=1; i<=n; i++){ for(int j=1; j<=n; j++){ dist[i][j]=map[i][j]=INF; pre[i][j]=i; } } for(int i=1; i<=m; i++){ scanf("%d %d %d",&u,&v,&cost); if(dist[u][v]>cost) //重边 map[u][v]=map[v][u]=dist[u][v]=dist[v][u]=cost; } // floyd minc=INF; for(int k=1; k<=n; k++){ // k还没加入(i,j)最短路,更新最短环 for(int i=1; i<k; i++){ for(int j=i+1; j<k; j++){ int ans=dist[i][j]+map[i][k]+map[k][j]; if(ans<minc){ //找到最优解 minc=ans; num=0; int p=j; while(p!=i){ //逆向寻找前驱遍历的路径并将其存储起来 path[num++]=p; p=pre[i][p]; } path[num++]=i; path[num++]=k; } } } //用k更新i到j的最短路径 for(int i=1; i<=n; i++){ for(int j=1; j<=n; j++){ if(dist[i][j]>dist[i][k]+dist[k][j]){ dist[i][j]=dist[i][k]+dist[k][j]; pre[i][j]=pre[k][j]; } } } }// end Floyd if(minc==INF) puts("No solution."); else{ printf("%d",path[0]); for(int i=1; i<num; i++) printf(" %d",path[i]); puts(""); } } return 0; }
相关文章推荐
- 【BLE】CC2541之OAD
- windows 桌面字体大小修改
- [LeetCode]Summary Ranges
- python 在爬虫中timeout设置超时有什么作用
- Windows8下安装ubuntu 15.10 实现双系统并使用mentohust连接锐捷校园网
- POJ 3667 线段树区间合并
- [AngularJS] Services, Factories, and Providers -- Service vs Factory
- android日历控件(一)
- 获取当前页面的所有链接的四种方法对比(python 爬虫)
- 现代软件工程讲义 源代码管理
- String内幕
- Nginx Resource
- 滴滴快车奖励政策,高峰奖励,翻倍奖励,按成交率,指派单数分级(12月14日)
- (转)Java二进制指令代码解析
- Javascript_设置表单的提交地址
- html5前端开发笔记-个人中心
- iis 搭建ftp
- VM连不上网解决方法总结
- 黑客攻防技术宝典Web实战篇(一)Web应用程序技术基础
- Python中遇到的错误小结