## Minimum ring problem

### Minimal ring of undirected graph

Floyd algorithm can be used to deal with the minimum ring problem. To be exact, calculate the smallest ring by the way.

Floyd algorithm can find the multi-source shortest path of undirected graph. It can ensure that the outermost loop to k is obtained between all vertices 0... k − 1 0...k-1 0...k − 1 is the shortest path of the middle point. A ring has at least three vertices. We assume that there is a ring and that the largest node in the ring is k k k ， i i i and j j j are all related to k k k adjacent points. Then the maximum number is k k The minimum ring length of k is m p [ i ] [ k ] + m p [ j ] [ k ] + d i s [ i ] [ j ] mp[i][k]+mp[j][k]+dis[i][j] mp[i][k]+mp[j][k]+dis[i][j], where d i s [ i ] [ j ] dis[i][j] dis[i][j] is represented by 0... k − 1 0...k-1 0...k − 1 is the shortest path at the middle point, which is consistent with the case when Floyd's outermost layer circulates to k. Right now i i i and j j j cycle all numbers less than k k k vertex combination can be found, and the maximum number is k k The smallest ring of k. Then go through the outermost layer k k k loop, you can find the smallest ring of the whole graph.

int ans = inf; for(int i = 1;i <= n;++i) for(int j = 1;j <= n;++j) dp[i][j] = mp[i][j]; for(int k = 1;k <= n;++k) { for(int i = 1;i < k;++i) for(int j = 1;j < i;++j) if(ans > dp[i][j] + mp[j][k] + mp[k][i]) ans = dp[i][j] + mp[j][k] + mp[k][i]; for(int i = 1;i <= n;++i) for(int j = 1;j <= n;++j) if(dp[i][j] > dp[i][k] + dp[k][j]) dp[i][j] = dp[i][k] + dp[k][j]; } return ans; }

### Minimal ring of digraph

#### Topological sorting

Topological sorting is for directed acyclic graphs. You can judge whether a ring is formed by checking whether all the last input degrees are reduced to 0. Disadvantages: it is impossible to know which ring is the smallest ring.

#### Joint search set

When we look up our ancestors and find ourselves, it shows that there is a ring. You can record the number of traversals while looking for ancestors. When you finally find yourself, compare it with the length of the current minimum ring to see whether it needs to be updated. Note: this side does not need to be connected, otherwise it will enter an endless loop.

#include<bits/stdc++.h> using namespace std; #define ll long long #define MAXN 200005 int ans=0x3f3f3f3f;//Number of minimum rings int f[MAXN]; ll n; int cnt; int findx(int x,int &cnt) { cnt++; if(x==f[x]) return x; else return findx(f[x],cnt); } void solve() { cin>>n; for(int i=1;i<=n;i++) f[i]=i; for(int i=1;i<=n;i++) { int temp; cnt=0; cin>>temp; int goal=findx(temp,cnt); if(goal==i) { ans=min(ans,cnt); } else f[i]=temp; } cout<<ans<<endl; } int main() { ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); solve(); return 0; }

#### Minimal ring of weighted graph

The weight of the ring is two nodes connected by edges i , j i,j i. The direct distance of J plus i , j i,j i. J does not contain edges ( i , j ) (i,j) The shortest circuit of (i,j).

Only when all the edge weights are 1, the union search algorithm can be established. If it is a weighted graph, it can still be taken on an undirected graph F l o y d Floyd Floyd algorithm needs to be used on directed graph D i j k s t r a Dijkstra Deformation of Dijkstra algorithm:

Enumerate each point as the starting point. After relaxing all the edges of the starting point, set the starting point d i s dis dis reset to I N F INF INF ， v i s i t visit visit reset to f a l s e false false . Then, when you sweep to the starting point, the value of the starting point d i s dis dis is the smallest ring. The complexity after heap optimization is O ( n ( n + m ) l o g n ) O(n(n+m)logn) O(n(n+m)logn)

The simple idea is to enumerate edges, break edges, and then find the shortest path. The complexity is O ( m ( n + m ) l o g n ) O(m(n+m)logn) O(m(n+m)logn)