HOJ12126
来源:互联网 发布:有没有发型设计软件 编辑:程序博客网 时间:2024/06/06 00:58
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<iostream>
const int inf = 0x3f3f3f3f;
bool vis[1001];
int x[1001],y[1001],t,n;
double dis[1001][1001],low[1001],ans,mn;
double dist(int x1,int y1,int x2,int y2)
{
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
double prim()
{
memset(vis,0,sizeof(vis));
vis[0]=1;
t=0;ans=0;
for(int i=0;i<n;i++)
low[i]=inf;
for(int i=1;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(vis[j]==0&&low[j]>dis[t][j])
low[j]=dis[t][j];
}
mn=inf;
for(int j=0;j<n;j++)
{
if(mn>low[j]&&vis[j]==0)
{
mn=low[j];
t=j;
}
}
vis[t]=1;
ans=ans+mn;
}
if(mn==inf)return 0;
return ans;
}
int main()
{
while(scanf("%d",&n),n)
{
for(int i=0;i<n;i++)
scanf("%d%d",&x[i],&y[i]);
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
dis[i][j]=dist(x[i],y[i],x[j],y[j]);//printf("%lf\n",dis[i][j]);}
}
printf("%4.2lf\n",prim());
}
}
本题最开始的做法是将第一个点放进一个数组里面,表示已经被选取的点,然后遍历所有点,找与之距离最小的点,放入集合,再次找与集合中的点距离最小的点,这样一来使得本题的复杂度为N^3,.而prim算法.找最小生成树思路和我处理的一样.不过值得学习的是prim算法里面将N^3变成N^2的处理方法..用vis[x]记录X点是否在生成树里面.遍历所有不在生成树里面的点,.寻找与生成树里面的点距离最近的点放入生成树,处理这里的时候是N^3变成N^2的关键,因为此算法不是遍历了所有生成树里面的点来求这个最短距离,而是每次新加入点进入生成树的时候,判断当前点与生成树外面的点的最小距离是不是小于当前生成树里面的点(不包括当前点),如果小于,则更新最小距离为当前点与生成树外面的最小距离,如此一来就不用再遍历所有在生成树里面的点了.
#include<stdlib.h>
#include<math.h>
#include<iostream>
const int inf = 0x3f3f3f3f;
bool vis[1001];
int x[1001],y[1001],t,n;
double dis[1001][1001],low[1001],ans,mn;
double dist(int x1,int y1,int x2,int y2)
{
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
double prim()
{
memset(vis,0,sizeof(vis));
vis[0]=1;
t=0;ans=0;
for(int i=0;i<n;i++)
low[i]=inf;
for(int i=1;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(vis[j]==0&&low[j]>dis[t][j])
low[j]=dis[t][j];
}
mn=inf;
for(int j=0;j<n;j++)
{
if(mn>low[j]&&vis[j]==0)
{
mn=low[j];
t=j;
}
}
vis[t]=1;
ans=ans+mn;
}
if(mn==inf)return 0;
return ans;
}
int main()
{
while(scanf("%d",&n),n)
{
for(int i=0;i<n;i++)
scanf("%d%d",&x[i],&y[i]);
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
dis[i][j]=dist(x[i],y[i],x[j],y[j]);//printf("%lf\n",dis[i][j]);}
}
printf("%4.2lf\n",prim());
}
}
本题最开始的做法是将第一个点放进一个数组里面,表示已经被选取的点,然后遍历所有点,找与之距离最小的点,放入集合,再次找与集合中的点距离最小的点,这样一来使得本题的复杂度为N^3,.而prim算法.找最小生成树思路和我处理的一样.不过值得学习的是prim算法里面将N^3变成N^2的处理方法..用vis[x]记录X点是否在生成树里面.遍历所有不在生成树里面的点,.寻找与生成树里面的点距离最近的点放入生成树,处理这里的时候是N^3变成N^2的关键,因为此算法不是遍历了所有生成树里面的点来求这个最短距离,而是每次新加入点进入生成树的时候,判断当前点与生成树外面的点的最小距离是不是小于当前生成树里面的点(不包括当前点),如果小于,则更新最小距离为当前点与生成树外面的最小距离,如此一来就不用再遍历所有在生成树里面的点了.