http://www.cnblogs.com/Yz81128/archive/2012/08/15/2640940.html

求最小环

floyd求最小环
2011-08-14 9:42

1 定义:

通常来说最小环是针对有向图而言

从一个点出发,经过一条简单路径回到起点成为环.图的最小环就是所有环中长度最小的.

2.怎样求最小环呢?

1传统的解决方法(dijkstra):
        任意一个环的权值,我们都可以看成两个有边相连的结点i、j的直接距离加上i、j间不包含边(边i->j)的最短路径。求最短路径我们第一个想到的就是Dijkstra算法。而Dijkstra所求的是一个点到所有点的最短距离。用Dijkstra所求的i、j的最短距离一定是i、j的直接距离(如果i,j连通),所以我们需要先将i、j的边从图中删除(若i,j不连通,则不用删除),再用Dijkstra求新图中i、j的最短距离即可。所以我们每次在图中选取一条边,把它从图中删掉.然后对删掉的那条边所对应的2点进行Dijkstra,也就是m次Dijkstra。

2.floyd求最小环:

抛开Dijkstra算法,进而我们想到用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的最小环。

3.模板

#include<algorithm>
using namespace std;

const int MAXN=105;
const int INF=10000000;

int dist[MAXN][MAXN],g[MAXN][MAXN];
int fa[MAXN][MAXN],path[MAXN];

int n,m,num,minc;

void Floyd()
{
     int i,j,k,p,tmp;
     minc=INF;
     for(k=1;k<=n;k++)
     {
         for(i=1;i<k;i++)
          for(j=i+1;j<k;j++)
          {
              tmp=dist[i][j]+g[i][k]+g[k][j];
              if(tmp<minc) //找到更优解
              {
                  minc=tmp;
                  num=0;
                  p=j;
                  while(p!=i) //逆向寻找前驱结点直到找到最前面的i,i->…->j
                  {
                        path[num++]=p;
                        p=fa[i][p];//fa[i][j]保存的不是k,而是fa[k][j].
                  }
                  path[num++]=i;
                  path[num++]=k;
              }
          }
         for(i=1;i<=n;i++)
          for(j=1;j<=n;j++)
          {
             tmp=dist[i][k]+dist[k][j];
             if(dist[i][j]>tmp)
             {
                 dist[i][j]=tmp;
                 fa[i][j]=fa[k][j];
             }
          }
     }
}

int main()
{
    int i,j,u,v,w;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
          for(i=1;i<=n;i++)
           for(j=1;j<=n;j++)
           {
               g[i][j]=INF;
               dist[i][j]=INF;
               fa[i][j]=i;
           }
          while(m--)
          {
               scanf("%d%d%d",&u,&v,&w);
               w=min(g[u][v],w);          //处理重边
               g[u][v]=g[v][u]=dist[u][v]=dist[v][u]=w;
          }
          Floyd();
          if(minc==INF)
               printf("No solution.\n");
          else
          {
               printf("%d",path[0]);
               for(i=1;i<num;i++)
                   printf(" %d",path[i]);
               printf("\n");
          }
    }
    system("pause");
    return 0;
}

转载于:https://www.cnblogs.com/thefirstfeeling/p/4410782.html

floyd求最小环 模板相关推荐

  1. 多源最短路径Floyd、Floyd求最小环【模板】

    Floyd算法:用来找出每对点之间的最短距离.图可以是无向图,也可以是有向图,边权可为正,也可以为负,唯一要求是不能有负环.  1.初始化:将Map[][]中的数据复制到Dist[][]中作为每对顶点 ...

  2. 2017百度之星程序设计大赛 - 资格赛【1001 Floyd求最小环 1002 歪解(并查集),1003 完全背包 1004 01背包 1005 打表找规律+卡特兰数】...

    度度熊保护村庄 Accepts: 13 Submissions: 488 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/3276 ...

  3. 最小环 floyd java_干货|Floyd求最小环(CF Shortest Cycle)

    作者:Water_Fox 来源:牛客网 You are given nn integer numbers a1,a2,-,ana1,a2,-,an. Consider graph on nn node ...

  4. hdu 1599(Floyd求最小环)

    find the mincost route Time Limit: 1000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/O ...

  5. floyd求最小环——poj1734Sightseeing trip

    题目链接 Description There is a travel agency in Adelton town on Zanzibar island. It has decided to offe ...

  6. hdu 1599 find the mincost route(找无向图最小环)(floyd求最小环)

    ps(我到今天才知道Floyd的核心思想是动态规划==) hdu 1599 find the mincost route(找无向图最小环) 注意!这里写成   #define data 0x3f3f3 ...

  7. POJ1734(floyd求最小环的路径)

    题目:Sightseeing trip 题意:求一个图中最小环,输出路径. #include <iostream> #include <string.h> #include & ...

  8. Acwing 344.观光之旅(Floyd求最小环)

    Acwing 344.观光之旅 题意 给定一张无向图,求图中一个至少包含 3 个点的环,环上的节点不重复,并且环上的边的长度之和最小. 该问题称为无向图的最小环问题. 你需要输出最小环的方案,若最小环 ...

  9. POJ1734 Sightseeing trip floyd求最小环问题

    问题描述 m个点, m条边, 求图中存在的路径最小的环 样例 Sample Input 5 7 1 4 1 1 3 300 3 1 10 1 2 16 2 3 100 2 5 15 5 3 20 Sa ...

最新文章

  1. 一不小心就让Java开发者踩坑的fail-fast是个什么鬼?
  2. Java Spring源代码学习之DispatcherServlet.getHandler
  3. 放弃 Windows 后 ,开源操作系统能成为主流桌面系统吗?
  4. Python通过WMI读取主板BIOS信息
  5. ORACLE查看某个表空间里有哪些表
  6. java byte[]如何移动位置_《北京尚学堂学习》——java基础
  7. Linux 网易云音乐问题汇总
  8. JS打开新页面的两种方式:当前页面打开和新页面打开
  9. ZZULIOJ1096-1100Python解法
  10. WordPress网站更改后台登录地址保姆级图文教程
  11. linux中如何判断两个字符串相等
  12. 数据结构初学之循环队列补充
  13. 解决mac Cornerston的Authentication provider raised an exception 更新失败问题
  14. [英语阅读]边听音乐边运动能提高智商吗
  15. 为什么蚂蚁金服的 ZSearch 比 ElasticSearh 还牛逼?
  16. spring boot 启动报错Log4j2 could not find a logging implementation 解决
  17. 关键词词云怎么做_自媒体人必备!一键搞定高逼格词云图片
  18. matlab编程反演S参数求电磁参数,VB调用Matlab在瞬变电磁法反演中的应用
  19. Matlab|基于时间序列预测的粒子群优化混合非线性回归和自回归技术的比较
  20. 【Unity3D】10行代码实现一个简单的角色移动旋转脚本

热门文章

  1. MySQL 我们来聊聊 count(*) 语句的优化方式有哪些?
  2. Android中去掉显示标题的方法
  3. java基础—面向对象——变量的区别
  4. [转帖]web安全:通俗易懂,以实例讲述破解网站的原理及如何进行防护!如何让网站变得更安全。...
  5. 利用virt-manager,xmanager, xshell启动界面来管理虚拟机
  6. 【HEVC帧间预测论文】P1.2 An Efficient Inter Mode Decision Approach for H.264 Video Codin
  7. Cucumber 相关资源
  8. 数据--dp,线段树优化
  9. jQuery源码研究分析学习笔记-jQuery.deferred()(12)
  10. 用calloc()函数分配内存