题目
题解思路
一开始想DFS爆搜,结果一样TLE。后来不断看博客和视频,才明白这是最小环和最短路径一起的问题。花的钱就是路径长度一样的概念,图是连通图,注意看题目,解析看核心代码或者视频。
视频地址
核心代码
先将图导入二维数组,再建一个由Floyd优化的最短路数组。
将最小环放入断点K里面并且不能超过K,因为这样由小到大遍历我们必然能出结果。floryd放后面是因为先将K断开能求出此时最小环更新答案后再用k值去更新最短路。这样前面的最小环求法的路径是被前一个K优化了的。
void floyd()
{
int ans=big;
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,dic[i][j]+xian[k][i]+xian[j][k]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
dic[i][j]=min(dic[i][j],dic[i][k]+dic[k][j]);
}
if(ans!=big)
printf("%d\n",ans);
else
printf("It's impossible.\n");
return ;
}
AC代码
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int xian[105][105];
int dic[105][105];
int n,m;
const int big=100006;
void floyd()
{
int ans=big;
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,dic[i][j]+xian[k][i]+xian[j][k]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
dic[i][j]=min(dic[i][j],dic[i][k]+dic[k][j]);
}
if(ans!=big)
printf("%d\n",ans);
else
printf("It's impossible.\n");
return ;
}
int main ()
{
while(~scanf("%d%d",&n,&m))
{ for(int j=1;j<=n;j++)
for(int k=1;k<=n;k++)
xian[j][k]=xian[k][j]=dic[j][k]=dic[k][j]=big;
for(int j=1;j<=m;j++)
{
int t,p,s;
scanf("%d%d%d",&t,&p,&s);
if(xian[t][p]>s)
xian[t][p]=xian[p][t]=dic[t][p]=dic[p][t]=s;
}
floyd();
}
return 0;
}