1. 程式人生 > >floyd改進版求最小環

floyd改進版求最小環

最小環改進演算法的證明
設一個環中的最大結點為k(編號最大), 與他相連的兩個點為i, j, 這個環的最短長度為g[i][k]+g[k][j]+i到j的路徑中所有結點編號都小於k的最短路徑長度。

根據floyd的原理, 在最外層迴圈做了k-1次之後, dist[i][j]則代表了i到j的路徑中所有結點編號都小於k的最短路徑綜上所述,該演算法一定能找到圖中最小環。

先上模板:

#include<bits/stdc++.h>
using namespace std;
int dis[111][111],e[111][111];
int n,m;
int main()
{
    int a,b,c;
    while(cin>>n>>m){
        memset(dis,0x3f,sizeof(dis));
        memset(e,0x3f,sizeof(e));
        for(int i=0;i<m;i++){
            cin>>a>>b>>c;
            e[a][b]=c;
            e[b][a]=c;
            dis[a][b]=c;
            dis[b][a]=c;
        }
        int ans=0x3f3f3f3f;
        for(int k=1;k<=n;k++){
            for(int i=1;i<=k-1;i++)
            {
                for(int j=i+1;j<=k-1;j++){
                    ans=min(ans,dis[i][j]+e[i][k]+e[k][j]);
                }
            }
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++){
                    dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
                }
            }
        }
        if(ans==0x3f3f3f3f) cout<<"沒有最小環"<<endl;
        else{
            cout<<"最小環長度為:"<<ans<<endl;
        }
    }
}

直接上程式碼:

#include<algorithm>
#include<iostream>
#include<cstdio>
 
using namespace std;
const int maxn = 105;
const int inf = 1e8;
int n,m;
int dis[maxn][maxn],mp[maxn][maxn];//dis表示最短路徑,mp表示兩點間直線距離(題中給出的值存入mp) 
void floyd(){
    int MinCost = inf;
    for(int k=1;k<=n;k++){
        for(int i=1;i<k;i++)
            for(int j=i+1;j<k;j++)
                MinCost = min(MinCost,dis[i][j]+mp[i][k]+mp[k][j]);//更新k點之前列舉ij求經過ijk的最小環
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);      //更新k點
    }
    if(MinCost==inf)puts("It's impossible.");
        else printf("%d\n",MinCost);
    }
int main()
{
    while(scanf("%d%d",&n,&m) == 2){
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            mp[i][j]=dis[i][j]=inf;
    for(int i=0;i<m;i++){
        int u,v,w;
        scanf("%d%d%d",&u,&v,&w);
        mp[u][v]=mp[v][u]=dis[u][v]=dis[v][u]=min(w,mp[u][v]);
    }
    floyd();
	}
    return 0;
}