floyd求最小环+例题(hdu1599)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1599

    题目要求求无向图中的最小环,如果只用floyd暴力求解mp[ i ][ i ]的话会发现有问题,比如1->2 , 2->3 ,得出1-> 3 ,那 3 - > 1 == 1->3 , 图就变成了1->2 , 2->3 , 3->2 , 2->1,这个讲道理不能算作一个环,那么就要用另一种方法来求最小环,

   比如先用(1-k-1)松弛一下图,接着用边(i,k)和(k,j)得出另一条路径,由于 i-j 的路径还没有被k松弛过,所以(i,k)和(k,j)的路径和(i,j)的路径一定不相同,但这时我们还无法保证当前是最短的所以每个情况都要考虑到从而

   得到最小的环

   

#include<bits/stdc++.h>
using namespace std;
#define INT_MAX 0x73f3f3f
int mp[110][110];
int dist[110][110];
void intt(){
    for(int i=0;i<110;i++)
        for(int j=0;j<110;j++)
            if(i==j) mp[i][j]=dist[i][j]=0;
            else dist[i][j]=mp[i][j]=INT_MAX;
}
int main()
{
    int m,n;
    while(~scanf("%d %d",&m,&n)){
        intt();
        int ans=INT_MAX;
        for(int i=0;i<n;i++){
            int a,b,c;
            scanf("%d %d %d",&a,&b,&c);
            if(mp[a-1][b-1]>c) mp[a-1][b-1]=dist[a-1][b-1]=c;
            if(mp[b-1][a-1]>c) mp[b-1][a-1]=dist[b-1][a-1]=c;
        }
//        for(int i=0;i<m;i++){
//            for(int j=0;j<m;j++){
//                printf("%d ",mp[i][j]);
//            }
//            printf("
");
//        }
        for(int k=0;k<m;k++){
            for(int i=0;i<k;i++){
                for(int j=i+1;j<k;j++){
                    //printf("++%d %d %d ---%d ---%d %d %d
",mp[i][k],mp[j][k],mp[i][j],ans,i,j,k);
                    ans=min(ans,(dist[i][k]+dist[j][k]+mp[i][j]));
                }
            }
//            for(int i=0;i<m;i++){
//                for(int j=0;j<m;j++){
//                    printf("%d ",mp[i][j]);
//                }
//                printf("
");
//            }

            for(int i=0;i<m;i++){
                for(int j=0;j<m;j++){
                    //if(i==j) continue;
                    mp[i][j]=min(mp[i][j],mp[i][k]+mp[j][k]);
                }
            }
        }
//        for(int i=0;i<m;i++){
//            for(int j=0;j<m;j++){
//                printf("%d ",mp[i][j]);
//            }
//            printf("
");
//        }

//        for(int i=0;i<m;i++){
//            if(mp[i][i]!=INT_MAX){
//                //if(ans==-1) ans=mp[i][i];
//                else ans=min(ans,mp[i][i]);
//            }
//        }
        if(ans!=INT_MAX) printf("%d
",ans);
        else printf("It's impossible.
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/fzw1523/p/11200759.html