floyd最小环&&模板
阅读原文时间:2023年07月09日阅读:2

;k<=n;k++){

     ;i<=n;i++){
         ;j<=n;j++){

             dis\[i\]\[j\]=min(dis\[i\]\[j\],dis\[i\]\[k\]+dis\[k\]\[j\]);

         }
     }
 }

通过中间节点k去松弛i到j的距离,这是floyd算法的核心

------------------------------------------------------------------------------------

floyd最小环是在floyd基础上的一点修改,问题大概是这样:求一条从源点出发,最后再返回源点的最短路线。

算法描述:对一张给定的图,我们可以通过如下形式寻环:u->k->v->u,其中v->….->u是一条不经过k的路径

ps:至少3点才能成环

寻环的部分有一个疑问:为什么寻环代码必须放在松弛代码的前面?

比如说 松弛的时候->dis[i][j]=maze[i][k]+maze[k][j],那么此时寻环部分放到松弛代码后面相当于一条路径来回走动,而不成环

1.两个点必然是不同的

2.初始的路径最短距离不能取0x3f3f3f3f,因为可能溢出

3.寻环代码必须在松弛代码前面

4.最外层的K是作为最大的节点

#include
#include
#include
#include
#include
#include
#include
#include
#include

using namespace std;
typedef long long ll;
;
const int inf=0x1f3f3f3f;//不能设置太大,用0x3f3f3f3f就wa了
int n,m,ans;
][];
][];
void floyd(){

 ans=inf;
 ;k<=n;k++){//前K-1个点的情况递推前K个点的情况

     //松弛之前枚举ij求经过ijk的最小环
     ;i<k;i++){
         ;j<k;j++){//注意了这里是i+1,//两个点必然是不同的

             //如果取inf为0x3f3f3f3f那么这里可能会爆精度
             //三点成环(从k点出发,回到k点)
             ans=min(ans,dis\[i\]\[j\]+maze\[i\]\[k\]+maze\[k\]\[j\]);

             //如果这部分代码放在后面,可能会导致
             // dis\[i\]\[j\]=maze\[i\]\[k\]+maze\[k\]\[j\]
             //相当于一条路径来回走动,而不成环
         }
     }

     ;i<=n;i++){
         ;j<=n;j++){

             dis\[i\]\[j\]=min(dis\[i\]\[j\],dis\[i\]\[k\]+dis\[k\]\[j\]);

         }
     }
 }
     if(ans!=inf)cout<<ans<<endl;
     else cout<<"It's impossible."<<endl;

}
void init(){

 ;i<=n;i++){
     ;j<=n;j++){

         if(i==j){
             maze\[i\]\[j\]=dis\[i\]\[j\]=;continue;
         }
          maze\[i\]\[j\]=dis\[i\]\[j\]=inf;
     }
 }

}
int main()
{
ios_base::sync_with_stdio(); cin.tie(); cout.tie();

 while(cin>>n>>m&&n&&m){
     ans=inf;
     init();//初始化

     ;i<=m;i++){

         int u,v,w;
         cin>>u>>v>>w;

         maze\[u\]\[v\]=maze\[v\]\[u\]=dis\[u\]\[v\]=dis\[v\]\[u\]=min(w,maze\[u\]\[v\]);

     }

     floyd();

 }

 ;

}

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器