今天学习了一些关于联通图的知识。主要就是学习了关于floyd算法的一些应用。具体的题目就是下面的一个模板题。
这就是一个很经典的模板题。 单向图,然后求最短路径。题目中没有说是某一个点到某一个点。我是给了你一个路径。然后我们就可以把它化解为路径中的第一个点到第二个点的最短路径以此就可以转化为一个可以用。floyd算法解决的问题。
而弗洛伊德算法也是比较简单的。就是通过一个三重循环。来将所有的可能找到以此找到最优解,核心代码就是下面这几行。
for(int k=1;k<=n;k++)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
s[i][j]=min(s[i][k]+s[k][j],s[i][j]);
}
}
}
然后完整代码就是下面这些。
#include<bits/stdc++.h>
using namespace std;
int n,m,ans=0;
int s[150][150],a[100000];
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d",&a[i]);
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&s[i][j]);
}
}
for(int k=1;k<=n;k++)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
s[i][j]=min(s[i][k]+s[k][j],s[i][j]);
}
}
}
for(int i=1;i<m;i++)
{
ans+=s[a[i]][a[i+1]];
}
printf("%d",ans);
return 0;
}
然后我还做了另外一道题。他也可以用这个算法解决。但是那个题所要求的数据比较少。所以我用了另外一种时间复杂度更低的算法。
这道题虽然也是求最短路径。但是他只要一到n也就是说只求两个点的最短路线。然后我就采用了时间复杂度更低的dp思想的算法来解决。通过从后往前遍历来不断找到最优解,为什么要从后往前?是因为我们要取的是第一个数据。也就是第一个点到n点的距离。所以我们就需要在判定这一点时,就要得到他之后所有点到达n点的最优解。而具体的代码就是如下。
#include<iostream>
#include<stdio.h>
#include<math.h>
using namespace std;
int a[2000][2000],i,j,n,dp[2000];
int main(){
scanf("%d",&n);
for(i=1;i<n;i++){
for(j=i+1;j<=n;j++)
scanf("%d",&a[i][j]);
dp[i]=1000000;
}
for(i=n-1;i>=1;i--){
for(j=i+1;j<=n;j++){
dp[i]=min(dp[i],a[i][j]+dp[j]);}}
printf("%d",dp[1]);
return 0;
}
好了,今天的学习总结就到这里了。