vijosP1046 观光旅游(最小环)
2015-10-26 14:58
441 查看
vijosP1046 观光旅游
链接:https://vijos.org/p/1046
【思路】
Floyd求解最小环。
【代码】
View Code
【参考代码及原理】
转载地址:http://blog.csdn.net/jarily/article/details/8872487
链接:https://vijos.org/p/1046
【思路】
Floyd求解最小环。
【代码】
#include<iostream> using namespace std; const int maxn = 100+10; const int INF=1e8; int f[maxn][maxn],dist[maxn][maxn]; int n,m,min_loop; void Floyd() { min_loop=INF; for(int k=1;k<=n;k++) { for(int i=1;i<k;i++) for(int j=i+1;j<k;j++) if(f[i][j]+dist[i][k]+dist[k][j]<min_loop) min_loop=f[i][j]+dist[i][k]+dist[k][j]; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(f[i][k]<INF && f[k][j]<INF) f[i][j]=min(f[i][j],f[i][k]+f[k][j]); } } int main() { ios::sync_with_stdio(false); while(cin>>n>>m) { for(int i=1;i<=n;i++) { f[i][i]=dist[i][i]=0; for(int j=i+1;j<=n;j++) f[i][j]=f[j][i]=dist[i][j]=dist[j][i]=INF; } int u,v,w; for(int i=0;i<m;i++) { cin>>u>>v>>w; dist[u][v]=dist[v][u]=f[u][v]=f[v][u]=w; } Floyd(); if(min_loop==INF) cout<<"No solution.\n"; else cout<<min_loop<<"\n"; } return 0; }
View Code
【参考代码及原理】
/* *算法引入: *求一个图G中的最小环路的朴素算法为:每次找到一条边,删除了求这两点之间的最短路径; *若能求出,则这条最短路径与原来的边构成一个环,不过时间复杂度略高; * *算法思想; *Floyd算法是按照顶点的编号增加的顺序更新最短路径的; *如果存在最小环,则会在这个环中的点编号最大的那个点u更新最短路径之前发现这个环; *即当点u被拿来更新i到j的最短路径的时候,可以发现这个闭合环路; *发现的方法是,更新最短路径前,遍历i,j点对,一定会发现某对i到j的最短路径长度: *dist[i][j]+map[j][u]+map[u][i]!=INF,这时s的i和j是当前环中挨着点u的两个点; *因为在之前的最短路径更新过程中,u没有参与更新,所以dist[i][j]所表示的路径中不会有点u,即一定为一个环; * *如果在每个新的点拿来更新最短路径之前遍历i和j验证上面的式子,虽然不能遍历到所有的环; *但是由于dist[i][j]是i到j点的最短路径m所以肯定可以遍历到最小的环; * *如果有负权环,则该算法失效,因为包含负环的图上,dist[i][j]已经不能保证i到j的路径上不会经过同一个点多次了; * *算法测试: *PKU1734(Sightseeing trip) */ #include<iostream> #include<cstring> #include<cstdlib> #include<queue> #include<cstdio> #include<climits> #include<algorithm> using namespace std; const int N=111; const int INF=0xffffff; int min_loop; int num; int map ,dist ,pre ; int path ; int n,m; void dfs(int i,int j) { int k=pre[i][j]; if(k==0) { path[num++]=j; return; } dfs(i,k); dfs(k,j); } void Floyd() { min_loop=INF; memset(pre,0,sizeof(pre)); for(int k=1; k<=n; k++) { for(int i=1; i<k; i++) //i<k { for(int j=i+1; j<k; j++) //j<k { if(dist[i][j]+map[i][k]+map[k][j]<min_loop) { min_loop=dist[i][j]+map[i][k]+map[k][j]; num=0; path[num++]=i; dfs(i,j); path[num++]=k; } } } for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { if(dist[i][k]+dist[k][j]<dist[i][j]) { dist[i][j]=dist[i][k]+dist[k][j]; pre[i][j]=k; } } } } } int main() { // freopen("C:\\Users\\Administrator\\Desktop\\kd.txt","r",stdin); while(~scanf("%d%d",&n,&m)) { for(int i=1; i<=n; i++) { for(int j=i+1; j<=n; j++) map[i][j]=map[j][i]=dist[i][j]=dist[j][i]=INF; map[i][i]=dist[i][i]=0; } for(int i=0; i<m; i++) { int u,v,w; scanf("%d%d%d",&u,&v,&w); if(w<map[u][v]) { map[u][v]=map[v][u]=w; dist[u][v]=dist[v][u]=w; } } Floyd(); if(min_loop==INF) puts("No solution."); else { for(int i=0; i<num-1; i++) printf("%d ",path[i]); printf("%d\n",path[num-1]); } } return 0; }
转载地址:http://blog.csdn.net/jarily/article/details/8872487
相关文章推荐
- Python WMI获取Windows系统信息 监控系统
- WebGL With Three.js – Lesson 6(转)
- rank
- android开发之sqlite数据库增删改查
- ABAP日期函数应用
- C++给函数传数组参数
- SQL RDBMS
- Android程序启动程序与页面的跳转
- Hibernate 、多表关联映射 - 多对多关系映射(many-to-many)
- <a>标签在微信iOS版本的解析没有问题,但是在安卓版就解析不出来
- 学习Hadoop笔记(一)
- 解决数据小位数问题
- 从无头单链表中删除节点
- QNX系统中播放wav文件
- Spark RDD的动作
- Web API应用架构在Winform混合框架中的应用(4)--利用代码生成工具快速开发整套应用
- 七层网络协议
- [转载] MFC绘制动态曲线,用双缓冲绘图技术防闪烁
- Hibernate 、多表关联映射 - 多对多关系映射(many-to-many)
- Could not create the Java virtual machine