图的最小环(Floyd算法)
时间:2019-09-25
本文章向大家介绍图的最小环(Floyd算法),主要包括图的最小环(Floyd算法)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
题目:
给出一个有向图,求它的最小环。
有向图的环应至少含2个顶点,而无向图的一个环至少含3个顶点。
简述:
如果熟悉floyd算法的原理,那么便知道,每次循环都是由最外层的k去松弛点与点之间的距离的,那么对于当前dis[i][j]还未加入k进行松弛,如果有dis[i][j]+map[i][k]+map[k][j]<mincircle,那么此时的i与j的路径和k便形成了一个最小环,然后加入k进行松弛,求下一次能否通过其他点进行松弛而得到最小环,注意求最小环的时候要每更新一个,便求一次路径,不能等到最后才求,,原因是最后的pre数组与当前并不一致。
无向图代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cctype> 4 #include<vector> 5 #include<queue> 6 #include<cstring> 7 #include<algorithm> 8 #define numm ch-48 9 #define pd putchar(' ') 10 #define pn putchar('\n') 11 #define pb push_back 12 #define debug(args...) cout<<#args<<"->"<<args<<endl 13 #define bug cout<<"************" 14 using namespace std; 15 template <typename T> 16 void read(T &res) { 17 bool flag=false;char ch; 18 while(!isdigit(ch=getchar())) (ch=='-')&&(flag=true); 19 for(res=numm;isdigit(ch=getchar());res=(res<<1)+(res<<3)+numm); 20 flag&&(res=-res); 21 } 22 template <typename T> 23 void write(T x) { 24 if(x<0) putchar('-'),x=-x; 25 if(x>9) write(x/10); 26 putchar(x%10+'0'); 27 } 28 typedef long long ll; 29 const int maxn=110+10; 30 const int maxm=50010; 31 const int inf=0x3f3f3f3f; 32 const int mod=1e9+7; 33 int a[maxn][maxn],dis[maxn][maxn],pre[maxn][maxn]; 34 vector<int>ans; 35 bool floyed(int n) { ///判最小环 36 int mircle=inf; 37 bool flag=false; 38 for(int k=1;k<=n;k++) { 39 for(int i=1;i<k;i++) 40 for(int j=i+1;j<k;j++) { ///如果环需要至少包含3个点,则i!=j!=k 41 if(dis[i][j]!=inf&&a[i][k]!=inf&&a[k][j]!=inf) {///找到一个,便更新一次 42 if(mircle>dis[i][j]+a[i][k]+a[k][j]) { 43 mircle=dis[i][j]+a[i][k]+a[k][j]; 44 flag=true; 45 ans.clear(); 46 ans.push_back(k); 47 ans.push_back(j); 48 int d=j; 49 do { 50 d=pre[i][d]; 51 ans.push_back(d); 52 }while(d!=i); 53 } 54 } 55 } 56 for(int i=1;i<=n;i++) { ///如果环需要至少包含3个点,则i!=j!=k 57 if(i!=k) 58 for(int j=1;j<=n;j++) { 59 if(i!=j&&j!=k&&dis[i][k]!=inf&&dis[k][j]!=inf) { 60 if(dis[i][j]>dis[i][k]+dis[k][j]) { 61 dis[i][j]=dis[i][k]+dis[k][j]; 62 pre[i][j]=pre[k][j]; ///attention!!! 63 } 64 } 65 } 66 } 67 } 68 return flag; 69 } 70 int main() 71 { 72 int m,n; 73 read(n),read(m); 74 memset(a,inf,sizeof(a)); 75 memset(dis,inf,sizeof(dis)); 76 for(int i=1;i<=n;i++) { 77 for(int j=1;j<=n;j++) 78 pre[i][j]=i; 79 } 80 for(int i=1;i<=m;i++) { 81 int u,v,w; 82 read(u),read(v),read(w); 83 a[u][v]=a[v][u]=dis[u][v]=dis[v][u]=w; 84 } 85 if(floyed(n)) { 86 for(int i=0;i<ans.size();i++) 87 write(ans[i]),pd; 88 pn; 89 } 90 else puts("No solution."); 91 return 0; 92 }
有向图代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cctype> 4 #include<vector> 5 #include<queue> 6 #include<cstring> 7 #include<algorithm> 8 #define numm ch-48 9 #define pd putchar(' ') 10 #define pn putchar('\n') 11 #define pb push_back 12 #define debug(args...) cout<<#args<<"->"<<args<<endl 13 #define bug cout<<"************" 14 using namespace std; 15 template <typename T> 16 void read(T &res) { 17 bool flag=false;char ch; 18 while(!isdigit(ch=getchar())) (ch=='-')&&(flag=true); 19 for(res=numm;isdigit(ch=getchar());res=(res<<1)+(res<<3)+numm); 20 flag&&(res=-res); 21 } 22 template <typename T> 23 void write(T x) { 24 if(x<0) putchar('-'),x=-x; 25 if(x>9) write(x/10); 26 putchar(x%10+'0'); 27 } 28 typedef long long ll; 29 const int maxn=2010+10; 30 const int maxm=50010; 31 const int inf=0x3f3f3f3f; 32 const int mod=1e9+7; 33 int a[maxn][maxn],dis[maxn][maxn],pre[maxn][maxn]; 34 int que[maxn+100],cnt; 35 bool floyed(int n) { ///有向图判最小环 36 int mincircle=inf; 37 bool flag=false; 38 for(int k=1;k<=n;k++) { 39 for(int i=1;i<=n;i++) { 40 if(a[k][i]==inf||a[k][i]>mincircle) continue; 41 for(int j=1;j<=n;j++) { 42 if(i==k&&j==k) continue; 43 if(dis[i][j]!=inf&&a[j][k]!=inf) { 44 if(mincircle>dis[i][j]+a[j][k]+a[k][i]) { 45 mincircle=dis[i][j]+a[j][k]+a[k][i]; 46 flag=true; 47 cnt=0; 48 que[++cnt]=k; 49 que[++cnt]=j; 50 int d=j; 51 do { 52 d=pre[i][d]; 53 if(d!=j&&d!=k) 54 que[++cnt]=d; 55 }while(d!=i); 56 57 } 58 } 59 } 60 } 61 for(int i=1;i<=n;i++) { 62 if(dis[i][k]==inf) continue; 63 for(int j=1;j<=n;j++) { 64 if(i==k&&j==k) continue; 65 if(dis[k][j]!=inf) { 66 if(dis[i][j]>dis[i][k]+dis[k][j]) { 67 dis[i][j]=dis[i][k]+dis[k][j]; 68 pre[i][j]=pre[k][j]; 69 } 70 } 71 } 72 } 73 } 74 return flag; 75 } 76 int main() 77 { 78 int m,n; 79 read(n),read(m); 80 memset(a,inf,sizeof(a)); 81 memset(dis,inf,sizeof(dis)); 82 for(int i=1;i<=n;i++) { 83 a[i][i]=dis[i][i]=0; 84 for(int j=1;j<=n;j++) 85 pre[i][j]=i; 86 } 87 for(int i=1;i<=m;i++) { 88 int u,v,w; 89 read(u),read(v),read(w); 90 a[u][v]=dis[u][v]=min(w,a[u][v]); 91 } 92 if(floyed(n)) { 93 for(int i=cnt;i;i--) 94 write(que[i]),pd; 95 pn; 96 } 97 else puts("No solution."); 98 return 0; 99 }
原文地址:https://www.cnblogs.com/wuliking/p/11584309.html
- 数据处理的统计学习(scikit-learn教程)
- 机器学习实战,使用朴素贝叶斯来做情感分析
- Python NLTK 处理原始文本
- 通过闪回事务查看数据dml的情况 (r2笔记69天)
- 通过shell和sql结合查找性能sql(r2笔记68天)
- 淘宝的评论归纳是用什么方法做到的?
- Python的机器学习实战:AadBoost
- 通过shell检查分区表中是否含有默认分区(r2笔记87天)
- 利用python爬取人人贷网的数据
- 通过shell脚本查看package的信息(r2笔记86天)
- 通过shell脚本查看procedure的信息(r2笔记85天)
- 支持中文文本数据挖掘的开源项目PyMining
- 通过分区键值发现性能问题(r2笔记84天)
- linux乱码和数据库乱码的问题简单排查(r2笔记83天)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法