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算法用来找出每对顶点之间的最短距离 ...
随机推荐
- SAP如何使用关于序列号的表
- iOS-音频格式转换-b
iOS处理音频过程中有时候需要不同格式的音频进行转换,最近需要将m4a格式的音频转换成wav,在网上搜索之后代码整理如下: - (void)convetM4aToWav:(NSURL *)origin ...
- Careercup - Facebook面试题 - 5761467236220928
2014-05-02 07:06 题目链接 原题: Given an array of randomly sorted integers and an integer k, write a funct ...
- 高质量的javascript代码 -- 深入理解Javascript
一. 编写高质量的javascript代码基本要点a) 可维护的代码(Writing Maintainable Code)i. 可读(注释)ii. 一致(看上去是同一个人写的)iii. 已记录b) 最 ...
- 编译dubbo2.5.4时遇到的问题及解决
dubbo的官方git地址为:https://github.com/alibaba/dubbo 按照其流程进行下载及编译,遇到的问题为: 1. 执行 mvn clean install -Dmaven ...
- javascript_22_for_二维数组
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- angular入门系列教程2
主题: 本篇主要介绍下angular里的一些概念,并且在咱们的小应用上加上点料.. 概念(大概了解即可,代码中遇到的会有详细注释): 模板:动态模板,是动态的,直接去处理DOM的,而不是通过处理字符串 ...
- xml存储图片 二进制存储图片
一.保存图片到XML文件 /// <summary> /// 保存图片到XML文件 /// </summary> private void UploadImageToXml() ...
- 果盟广告SDK
// // GuomobWallView.h // GuoMobWallSample // // Created by keyrun on 14-1-21. // Copyright (c) 2014 ...
- winform DataGridView控件开发经验
1.不让DataGridView控件自动生成列 设置AutoGenerateColumns 为false. dgTicket.AutoGenerateColumns = false; //将自动生成列 ...