最小环问题:都比较容易得到从u 到 v 经过中间某一些结点的最短路,但是我们得确保回来的时候,不能经过那些结点,这样我们就需要改一下floyd算法了
主要是思路不好想,理解了思路,代码就出来了,唯一的wa点没想到是我经常用的inf 0x3f3f3f3f太小了,以后用0xfffffff吧
#include <iostream>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 150;
int n,m,a,b,c;
int mp[maxn][maxn];//表示的正常从u到v经过k的最短路
int A[maxn][maxn];//表示的是不经过k的时候回来的时候的最短路
int floyd()
{
int retmin = INF;
for(int k = 1;k <= n;k++)
{
for(int i = 1;i < k;i++)//假设k为最大的结点,进行遍历优化,并且最后也不会包含最大的结点n
{
for(int j = i + 1;j < k;j++)
{
//为什么不更新优化mp数组呢,是因为这是一个暴力的循环,总能够找到最小值!
int tmp = A[i][j] + mp[i][k] + mp[k][j];
//这个时候A[i][j]还没有更新k结点!!因为下一层才开始更新……
if(tmp < retmin)retmin = tmp;
}
}
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= n;j++)
{
if(A[i][j] > A[i][k] + A[k][j])
A[i][j] = A[i][k] + A[k][j];
}
}
}
return retmin;
}
int main()
{
int i,j;
while(~scanf("%d%d",&n,&m))
{
//初始化
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= n;j++)
{
mp[i][j] = A[i][j] = INF;
}
}
//输入距离进行更新,防止重边的影响,自动定义为双向边
for(int i = 1;i <= m;i++)
{
scanf("%d%d%d",&a,&b,&c);
mp[a][b] = mp[b][a] = A[a][b] = A[b][a] = min(mp[a][b],c);
}
//进行floyd算法,寻找最小环
int s = floyd();
if(s == INF)
printf("It's impossible.\n");
else
printf("%d\n",s);
}
return 0;
}