最小环问题:都比较容易得到从u 到 v 经过中间某一些结点的最短路,但是我们得确保回来的时候,不能经过那些结点,这样我们就需要改一下floyd算法了

进而我们想到用Floyd算法。我们知道,Floyd算法在进行时会不断更新矩阵dist(k)。设dist[k,i,j]表示从结点i到结点j且满足所有中间结点,它们均属于集合{1,2,⋯ ,k}的一条最短路径的权。其中dist[0,i,j ]即为初始状态i到j的直接距离。对于一个给定的赋权有向图, 求出其中权值和最小的一个环。我们可以将任意一个环化成如下形式:u->k->v ->(x1-> x2-> ⋯ xm1)-> u(u与k、k与v都是直接相连的),其中v ->(x1-> 2-> ⋯ m)-> u是指v到u不经过k的一种路径。

在u,k,v确定的情况下,要使环权值最小, 则要求 (x1一>x2->⋯一>xm)->u路径权值最小.即要求其为v到u不经过k的最短路径,则这个经过u,k,v的环的最短路径就是:[v到u不包含k的最短距离]+dist[O,u,k]+dist[O,k,v]。我们用Floyd只能求出任意2点间满足中间结点均属于集合{1,2,⋯  ,k}的最短路径,可是我们如何求出v到u不包含k的最短距离呢?
         现在我们给k加一个限制条件:k为当前环中的序号最大的节点(简称最大点)。因为k是最大点,所以当前环中没有任何一个点≥k,即所有点都<k。因为v->(x1->x2->......xm)->u属于当前环,所以x1,x2,⋯ ,xm<k,即x1,x2.⋯。xm≤k一1。这样,v到u的最短距离就可以表示成dist[k一1 ,u,v]。dist[k一1,v,u]表示的是从v到u且满足所有中间结点均属于集合{1,2,⋯  ,k一1}的一条最短路径的权。接下来,我们就可以求出v到u不包含k的最短距离了。这里只是要求不包含k,而上述方法用的是dist[k一1,v,u],求出的路径永远不会包含k+l,k+2,⋯ 。万一所求的最小环中包含k+1,k+2,⋯ 怎么办呢?的确,如果最小环中包含比k大的节点,在当前u,k,v所求出的环显然不是那个最小环。然而我们知道,这个最小环中必定有一个最大点kO,也就是说,虽然当前k没有求出我们所需要的最小环,但是当我们从k做到kO的时候,这个环上的所有点都小于kO了.也就是说在k=kO时一定能求出这个最小环。我们用一个实例来说明:假设最小环为1—3—4—5—6—2—1。的确,在u=l,v=4,k=3时,k<6,dist[3,4,1]的确求出的不是4—5—6—2—1这个环,但是,当u=4,v=6,k=5或u=5,v=2,k=6时,dist[k,v,u]表示的都是这条最短路径.所以我们在Floyd以后,只要枚举u.v,k三个变量即可求出最小环。时间复杂度为O(n3)。我们可以发现,Floyd和最后枚举u,v,k三个变量求最小环的过程都是u,v,k三个变量,所以我们可以将其合并。这样,我们在k变量变化的同时,也就是进行Floyd算法的同时,寻找最大点为k的最小环。

主要是思路不好想,理解了思路,代码就出来了,唯一的wa点没想到是我经常用的inf 0x3f3f3f3f太小了,以后用0xfffffff吧

#include <iostream>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 150;
int n,m,a,b,c;
int mp[maxn][maxn];//表示的正常从u到v经过k的最短路
int A[maxn][maxn];//表示的是不经过k的时候回来的时候的最短路
int floyd()
{
int retmin = INF;
for(int k = 1;k <= n;k++)
{
for(int i = 1;i < k;i++)//假设k为最大的结点,进行遍历优化,并且最后也不会包含最大的结点n
{
for(int j = i + 1;j < k;j++)
{
//为什么不更新优化mp数组呢,是因为这是一个暴力的循环,总能够找到最小值!
int tmp = A[i][j] + mp[i][k] + mp[k][j];
//这个时候A[i][j]还没有更新k结点!!因为下一层才开始更新……
if(tmp < retmin)retmin = tmp;
}
}
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= n;j++)
{
if(A[i][j] > A[i][k] + A[k][j])
A[i][j] = A[i][k] + A[k][j];
}
}
}
return retmin;
}
int main()
{
int i,j;
while(~scanf("%d%d",&n,&m))
{
//初始化
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= n;j++)
{
mp[i][j] = A[i][j] = INF;
}
}
//输入距离进行更新,防止重边的影响,自动定义为双向边
for(int i = 1;i <= m;i++)
{
scanf("%d%d%d",&a,&b,&c);
mp[a][b] = mp[b][a] = A[a][b] = A[b][a] = min(mp[a][b],c);
}
//进行floyd算法,寻找最小环
int s = floyd();
if(s == INF)
printf("It's impossible.\n");
else
printf("%d\n",s);
}
return 0;
}

floyd算法之最小环问题的更多相关文章

  1. timus1004 最小环()Floyd 算法

    通过别人的数据搞了好久才成功,果然还是不够成熟 做题目还是算法不能融会贯通 大意即找出图中至少3个顶点的环,且将环中点按顺序输出 用floyd算法求最小环 因为floyd算法求最短路径是通过中间量k的 ...

  2. 图论——最短路:Floyd,Dijkstra,Bellman-Ford,SPFA算法及最小环问题

    一.Floyd算法 用于计算任意两个节点之间的最短路径. 参考了five20的博客 Floyd算法的基本思想如下:从任意节点A到任意节点B的最短路径不外乎2种可能,1是直接从A到B,2是从A经过若干个 ...

  3. [图论]Floyd 算法小结

    Floyd 算法小结  By Wine93 2013.11 1. Floyd算法简介 Floyd算法利用动态规划思想可以求出任意2点间的最短路径,时间复杂度为O(n^3),对于稠密图, 效率要高于执行 ...

  4. Floyd 算法求多源最短路径

    Floyd算法: Floyd算法用来找出每对顶点之间的最短距离,它对图的要求是,既可以是无向图也可以是有向图,边权可以为负,但是不能存在负环(可根据最小环的正负来判定). 基本算法: Floyd算法基 ...

  5. 温故知新 —— Floyd算法

    什么?Floyd?sb O(n ^ 3) 算法早不用了,右上角红叉吧.我之前虽然也认识过 Floyd 算法的重要性,不过多少也是这么想的.然而最近三天连续 rand 到了好几道有关的题目,让我彻底重新 ...

  6. 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 ...

  7. 多源最短路(floyd算法)

    Floyd算法: 如何简单方便的求出图中任意两点的最短路径 Floyd-Warshall算法(O(n)比较适用于边较多的稠密图(Dense Graph)) Floyd算法用来找出每对顶点之间的最短距离 ...

  8. 最短路径之Floyd算法

    Floyd算法又称弗洛伊德算法,也叫做Floyd's algorithm,Roy–Warshall algorithm,Roy–Floyd algorithm, WFI algorithm. Floy ...

  9. 最短路径—Dijkstra算法和Floyd算法

    原文链接:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html 最后边附有我根据文中Dijkstra算法的描述使用jav ...

随机推荐

  1. C++中的getline()

    总结: 尽量使用全局函数string类中的getline(),其读入的第二个参数为string类型,不设置默认是遇到回车停止读入操作 cin.getline是针对数组字符串的,以指定的地址为存放第一个 ...

  2. Linux使用touch批量修改文件/文件夹时间戳

      Linux下touch是一个非常有用的命令. touch语法结构如下: touch [-acfm][-d <日期时间>][-r <参考文件或目录>][-t <日期时间 ...

  3. Luogu 1341 无序字母对 - 欧拉路径

    Solution 找一条字典序最小的欧拉路径. 用 $multiset$ 存储领接表. 欧拉路径模板传送门 Code #include<cstdio> #include<cstrin ...

  4. Partition Array Into Three Parts With Equal Sum LT1013

    Given an array A of integers, return true if and only if we can partition the array into three non-e ...

  5. jmeter使用HTTP代理服务器

    浏览器>web服务器 浏览器>HTTP代理服务器>web服务器 jmeter>HTTP代理服务器>web服务器 浏览器>jmeter HTTP服务器>web服 ...

  6. jQuery学习笔记:基础

    本文主要总结jQuery中一些知识点 概念 美元符号$是著名的jQuery符号.jQuery把所有功能全部封装在一个全局变量jQuery中,而$也是一个合法的变量名,它是变量jQuery的别名 $本质 ...

  7. PHP 写文件的例子

    $contents = "All the content"; $dir = 'c:'; $file_path = $dir . "\\content.txt"; ...

  8. [C#]做服务使用Process启动外部程序没窗体

    这几天会到一个需要,要时时侦测文件生成,并上传到Server上,侦测文件生成使用的FileSystemWatch.但是时时运行遇到了问题,程序可能会人为退出或者意外终止,使用一个进程监控程序的监程,也 ...

  9. 20155312 2016-2017-2 《Java程序设计》第十周学习总结

    20155312 2016-2017-2 <Java程序设计>第十周学习总结 ## 课堂内容总结 数组 遍历数组: for(...,arr) for(i=0;i<arr.length ...

  10. css中元素的位置

    一.display 1.display:none 隐藏标签 2.display:inline 将块级标签改为内联标签 3.display:block 将内联标签改为块级标签 4.display:inl ...