8月7日总结

来源:互联网 发布:红酒网络销售好做吗 编辑:程序博客网 时间:2024/05/18 17:03

今天上午做了一个关于弗洛伊德算法的问题,下午学习了一下克鲁斯卡尔算法和普里姆算法,然后做了一个关于普里姆算法的问题。

1.Frogger(弗洛伊德问题):

题目大意:给你n块石头的坐标,有两只青蛙分别在一号石头和二号石头上。一号青蛙想去找二号青蛙,求他所走的最短路上的最大跳跃距离是多少。

代码:#include<iostream>
#include<cmath>
#include<iomanip>
using namespace std;
struct node
{
    int x,y;
}a[201];
int i,j,k,n,ca=0;
double len[201][201];
int main()
{
    while(cin>>n)
    {
        ca++;
        if(n==0)
        return 0;
        for(i=0;i<n;i++)
        cin>>a[i].x>>a[i].y;
        for(i=0;i<n;i++)
        for(j=0;j<n;j++)
        if(i!=j)
        len[j][i]=len[i][j]=sqrt(pow(a[i].x-a[j].x,2)+pow(a[i].y-a[j].y,2));
        for(k=0;k<n;k++)
        for(i=0;i<n;i++)
        for(j=0;j<n;j++)
        if(len[i][k]<len[i][j]&&len[k][j]<len[i][j])
        if(len[i][k]<len[k][j])
        len[i][j]=len[j][i]=len[k][j];
        else
         len[i][j]=len[j][i]=len[i][k];
        cout<<"Scenario #"<<ca<<endl<<"Frog Distance = ";
         cout << fixed <<setprecision(3)<<len[0][1]<<endl<<endl;
    }
    return 0;
}

解题思路:建立一个结构体数组,把各个点的横纵坐标存起来,然后通过两重循环把任意两块石头间的距离算出来,然后利用弗洛伊德算法的三重循环按照题意适当的改编,求出结果。

2.Highways(Prim问题):

题目大意:在 1-n 个城镇之间建设公路,求可以把所有城镇连接起来的最短路。

代码:#include<stdio.h>
#include<string.h>
using namespace std;
int g[501][501];
int minlen[501],u[501];
int i,j,k;
int main()
{
    int t,n;
    scanf("%d",&t);
    while(t--)
    {
         scanf("%d",&n);
        for(i=1;i<=n;i++)
        for(j=1;j<=n;j++)
        scanf("%d",&g[i][j]);
        int ans=-1;
        memset(minlen,0x7f,sizeof(minlen));
        memset(u,1,sizeof(u));
        minlen[1]=0;
        for(i=1;i<=n;i++)
        {
             int k=0;
            for(j=1;j<=n;j++)
            if(u[j]&&(minlen[j]<minlen[k]))
                k=j;
            u[k]=0;
            if(ans<minlen[k])
            ans=minlen[k];
            for(j=1;j<=n;j++)
            if(u[j]&&(g[k][j]<minlen[j]))
            minlen[j]=g[k][j];
        }
      printf("%d\n",ans);
        }
        return 0;
}

解题思路:感觉这个题就是纯普里姆算法没什么好说的,刚开始用c++提交的,超时,然后又用c交的ac了。

最小生成树:在有n个顶点的连通图中选取n-1条边,这n-1条边可以连接n个顶点,同时这n-1条边的边权之和是所有方案中最小的,有深度优先生成树和广度优先生成树两种方法。

Prim算法(普里姆算法):通过n-1次循环向生成树中添加n-1条最小的边,这样得到的生成树一定是最小的生成树。

算法思想:局部最优(贪心)+调整=全局最优

注意:一般采用邻接矩阵的方法进行存储。

Kruskal算法(克鲁斯卡尔算法):利用并查集来求最小生成树的算法。

注意:此算法也是用邻接矩阵的方法进行存储。



原创粉丝点击