AcWing算法提高课 Floyd求无向图最小环
主要思路为,在Floyd过程中,找到环中最大值为k的最小环
解释:
以dp的视角看待Floyd算法,在循环到k时,已经获得了经过前k-1个点的最短路径。
设环中最大标号为k,则路径可以表示为:i->k->j->...->i
i->k和k->j为直接相连,j->...->i为通过小于标号k的点相连。
当获得到比当前记录更小的环时,即可进行更新。
更新采用递归更新,即使用pos数组记录j->...->i的中间点,并递归两边获取环上全部点。

#include<bits/stdc++.h> #define fore(x,y,z) for(LL x=(y);x<=(z);x++) #define forn(x,y,z) for(LL x=(y);x<(z);x++) #define rofe(x,y,z) for(LL x=(y);x>=(z);x--) #define rofn(x,y,z) for(LL x=(y);x>(z);x--) #define pub push_back #define all(x) (x).begin(),(x).end() #define fi first #define se second using namespace std; typedef long long LL; typedef pair<int,int> PII; typedef pair<LL,LL> PLL; const int N=110; int n,m; int A_M[N][N]; int dis[N][N]; int pos[N][N]; int path[N]; int cnt; void GetPath(int i,int j) { if(pos[i][j]==0) return; int k=pos[i][j]; GetPath(i,k); path[cnt++]=k; GetPath(k,j); } void YD() { cin>>n>>m; memset(A_M,0x3f,sizeof(A_M)); fore(i,1,n) A_M[i][i]=0; while(m--) { int i,j,l; cin>>i>>j>>l; A_M[i][j]=A_M[j][i]=min(A_M[i][j],l); } memcpy(dis,A_M,sizeof(dis)); int res=1e9; fore(k,1,n) { forn(i,1,k) { forn(j,i+1,k) { if((LL)dis[i][j]+A_M[j][k]+A_M[k][i]<res) { res=dis[i][j]+A_M[j][k]+A_M[k][i]; cnt=0; path[cnt++]=k; path[cnt++]=i; GetPath(i,j); path[cnt++]=j; } } } fore(i,1,n) { fore(j,1,n) { if(dis[i][j]>dis[i][k]+dis[k][j]) { dis[i][j]=dis[i][k]+dis[k][j]; pos[i][j]=k; } } } } if(res==1e9) cout<<"No solution."<<endl; else { forn(i,0,cnt) cout<<path[i]<<' '; cout<<endl; } } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); int T=1; //cin >> T; while (T--) { YD(); } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人