timus1004 最小环()Floyd 算法
通过别人的数据搞了好久才成功,果然还是不够成熟
做题目还是算法不能融会贯通
大意即找出图中至少3个顶点的环,且将环中点按顺序输出
用floyd算法求最小环
因为floyd算法求最短路径是通过中间量k的增加而更新的
算法流程:
对于k,我们知道利用floyd算法求出任意两点i,j最短距离,仅通过路径i-()-j,其中()中的节点编号均<=k-1
可以这样证明:
设最小环上最大点的编号为k0;则当k=k0时,对于任意与k0相接两点i,j两者
1.对于环的剩下一部分必然是i到j的最短路径,因为最佳
2.最短路径必然是通过{1,...,k-1},否则该最小环最大编号必然大于k,故ans=f[i][j]+Graph[i][k]+Graph[j][k] (f[i][j]表示当前通过前k-1点为中间路径的i-j的最短路径)
故通过枚举k,取ans=min(ans,f[i][j]+Graph[i][k]+Graph[j][k]) 其中(i,j<k) 必能找到
而环顺序只需通过计算每次更新f[i][j]时的k记录pre[i][j]=k,之后通过递归即可得到,
需要注意的是:每次更新ans时就要将路径记录下来,不然之后可能路径会更新时被改变,这个改变可不代表路径还会缩短,首先要明白该算法必然能够求出最小环,故若求出最小环后可能之后缩短路径是会重边,即比如i到j的距离通过k后变短了,可是是重边得来的没有意义
#include<iostream>
#include<cstdio>
#include<cstring>
int f[105][105],pre[105][105],Graph[105][105],ans,a[1000];
const int maxn=100000000;
int print(int i,int j){
if (pre[i][j]==0) return 0;
print(i,pre[i][j]);
a[++a[0]]=pre[i][j];
print(pre[i][j],j);
return 0;
}
int main()
{
int i,j,k,l,n,m;
while(1){
scanf("%d",&n);
if (n==-1) break;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++){
f[i][j]=maxn;
Graph[i][j]=f[i][j];
}
memset(pre,0,sizeof(pre));
ans=maxn;
scanf("%d",&m);
for(i=1;i<=m;i++){
scanf("%d%d%d",&j,&k,&l);
if(f[j][k]>l) {f[j][k]=l;Graph[j][k]=l;}
if(f[k][j]>l) {f[k][j]=l;Graph[k][j]=l;}
}
for(k=1;k<=n;k++){
for(i=1;i<=k-1;i++)
for(j=1;j<=k-1;j++)
if(i!=j)
if(ans>f[i][j]+Graph[i][k]+Graph[j][k]){//此处不能用f[][]代替Graph[][] 容易举出实例
ans=f[i][j]+Graph[i][k]+Graph[j][k];
a[0]=0;
a[++a[0]]=i;
print(i,j);
a[++a[0]]=j;
a[++a[0]]=k;
}
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(i!=k&&j!=k&&i!=j)
if(f[i][j]>f[i][k]+f[k][j]){
f[i][j]=f[i][k]+f[k][j];
pre[i][j]=k;
pre[j][i]=k;
}
}
if(ans<maxn){
for(i=1;i<a[0];i++)
printf("%d ",a[i]);
printf("%d\n",a[a[0]]);
}else printf("No solution.\n");
}
return 0;
}
timus1004 最小环()Floyd 算法的更多相关文章
- 图的连通性问题之连通和最小环——Floyd算法
Floyd 判断连通性 d[i][j]仅表示i,j之间是否联通 ;k<=n;k++) ;i<=n;i++) ;j<=n;j++) dis[i][j]=dis[i][j]||(dis[ ...
- floyd算法之最小环问题
最小环问题:都比较容易得到从u 到 v 经过中间某一些结点的最短路,但是我们得确保回来的时候,不能经过那些结点,这样我们就需要改一下floyd算法了 进而我们想到用Floyd算法.我们知道,Floyd ...
- [图论]Floyd 算法小结
Floyd 算法小结 By Wine93 2013.11 1. Floyd算法简介 Floyd算法利用动态规划思想可以求出任意2点间的最短路径,时间复杂度为O(n^3),对于稠密图, 效率要高于执行 ...
- Floyd 算法求多源最短路径
Floyd算法: Floyd算法用来找出每对顶点之间的最短距离,它对图的要求是,既可以是无向图也可以是有向图,边权可以为负,但是不能存在负环(可根据最小环的正负来判定). 基本算法: Floyd算法基 ...
- 温故知新 —— Floyd算法
什么?Floyd?sb O(n ^ 3) 算法早不用了,右上角红叉吧.我之前虽然也认识过 Floyd 算法的重要性,不过多少也是这么想的.然而最近三天连续 rand 到了好几道有关的题目,让我彻底重新 ...
- hdu 1599 find the mincost route (最小环与floyd算法)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1599 find the mincost route Time Limit: 1000/2000 MS ...
- 最小环-Floyd
floyd求最小环 在Floyd的同时,顺便算出最小环. Floyd算法 :k<=n:k++) { :i<k:i++) :j<k:j++) if(d[i][j]+m[i][k]+m[ ...
- 最小环(floyd以及dijkstra实现+例题)
最小环定义 最小环是指在一个图中,有n个节点构成的边权和最小的环(n>=3). 一般来说,最小环分为有向图最小环和无向图最小环. 最小环算法: 直接暴力: 设\(u\)和\(v\)之间有一条边长 ...
- 多源最短路(floyd算法)
Floyd算法: 如何简单方便的求出图中任意两点的最短路径 Floyd-Warshall算法(O(n)比较适用于边较多的稠密图(Dense Graph)) Floyd算法用来找出每对顶点之间的最短距离 ...
随机推荐
- 团队项目之Sprint计划会议
一.我们团队在4月15日进行了冲刺计划会议,会议过程大致如下: 1.总结目前的工作进展,再一次确定所做项目的方向: 2.将之前的调查问卷的结果进行统计,做了需求分析,大致了解了用户的想法: 3.根据初 ...
- 关于windbg的认识
1.windbg是一个用于调试代码的工具,基础介绍:http://www.pediy.com/kssd/pediy10/94457.html 2.关于windbg和vs在代码调试方面的区别,参考:ht ...
- 阿旭的php开发环境
过了几年,php技术也日新月异,变化也挺多.哪么对于开发者,感觉有一些简单的方法,写下来,以备以后使用.我觉得吧,Linux写php不如windows写php,调试,查资料和各种功能比较全面,而lin ...
- 第五周技术博客发表 web 网页开发
<html><head> <title> HTML</title></head><body > <h1>会员注册界面 ...
- MATLAB三维散点图的绘制(scatter3、plot3)
MATLAB三维散点图的绘制(scatter3.plot3) (1)函数scatter3 用法:scatter3(x,y,z,'.',c) % c 为颜色,需和x,y,z长度相同 例子: x=[422 ...
- java Socket用法详解(转)
在客户/服务器通信模式中, 客户端需要主动创建与服务器连接的 Socket(套接字), 服务器端收到了客户端的连接请求, 也会创建与客户连接的 Socket. Socket可看做是通信连接两端的收发器 ...
- uva 10128
动归 转移方程 :dp(i, j, k) = dp(i – 1, j, k) * (i – 2) + dp(i – 1, j – 1, k) + dp(i – 1, j, k – 1) i表示此时排第 ...
- Unity3dBug - OnEnable
最近 项目 因为 使用 active 代替 instantiate机制,很多时候 OnEnable 代理 OnStart. 然后发现一个 奇怪的 问题 void Awake() { Debug.Log ...
- How does database indexing work?
When data is stored on disk based storage devices, it is stored as blocks of data. These blocks are ...
- hdu 4686 Arc of Dream
思路:构造矩阵 a[i]*b[i]=ax*bx*a[i-1]*b[i-1]+ax*by*a[i-1]+ay*bx*b[i-1]+ay*by 代码如下: #include<iostream> ...