刚学了prim,写了prim算法最经典的问题,
给出n点,求点阵中最小生成树,代码如下:
#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
const int MAX=100+5;
const double INF=0x7ffffff;
struct node{
double x,y;
}e[MAX];
bool vis[MAX];
double map[MAX][MAX];
double dist[MAX];
double dis(struct node a,struct node b)
{
return sqrt((a.x-b.x)*(a.x-b.x)*1.0+(a.y-b.y)*(a.y-b.y));
}
double prim(int n)
{
int i,j,mark;
double temp,ans;
memset(vis,0,n+2);
p[1]=1;ans=0;//定初始顶点为1,
vis[1]=1;
for(i=2;i<=n;i++)
dist[i]=map[1][i];
for(i=2;i<=n;i++)
{
temp=INF;
for(j=1;j<=n;j++)
if(vis[j]==0&&dist[j]<temp)
{
mark=j;
temp=dist[j];
}
vis[mark]=1;//标记已访问
ans+=dist[mark];
for(j=1;j<=n;j++)//更新顶点
if(!vis[j]&&map[mark][j]>=0&&map[mark][j]<dist[j])
dist[j]=map[mark][j];//dist【】存储未访问点与集合最小距离,此处更新该数组
}
return ans;
}
int main()
{
int N,n,i,j;
double ans;
cin>>N;
while(N--)
{
cin>>n;
for(i=1;i<=n;i++)
cin>>e[i].x>>e[i].y;
for(i=1;i<=n;i++)
for(j=i;j<=n;j++)
map[i][j]=map[j][i]=dis(e[i],e[j]);
ans=prim(n);
cout<<ans<<endl;
}
return 0;
}
额,下面附上我刚开始做的代码,复杂度较高。
分析:用node e[MAX}存储所有点,矩阵dist[i][j]存储点i与点j的距离,用p[MAX]来存储已加入集合的点,vis[MAX]标记该点是否被访问(另开数组而不遍历p【】,出于节约时间考虑),循环n-1次,每次寻找到集合中的点(既p【i】)与未加入集合点距离最小值,{将其并入集合p,并标记访问vis,加入结果ans}
#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
const int MAX=100+5;
const double INF=0x7ffffff;
struct node{
double x,y;
}e[MAX];
bool vis[MAX];
int p[MAX];
double dist[MAX][MAX];
double dis(struct node a,struct node b)
{
return sqrt((a.x-b.x)*(a.x-b.x)*1.0+(a.y-b.y)*(a.y-b.y));
}
double prim(int n)
{
int i,j,k,mark;
double temp,ans;
memset(p,0,n+2);
memset(vis,0,n+2);
p[1]=1;ans=0;
vis[1]=1;
for(i=2;i<=n;i++)
{
temp=INF;
for(j=1;j<i;j++)//用寻找集合中的点与未加入加入集合点距离最小值
{
for(k=1;k<=n;k++)
{
if(vis[k]==0&&dist[p[j]][k]<temp)
{
mark=k;temp=dist[p[j]][k];
}
}
}
vis[mark]=1;
p[i]=mark;
ans+=temp;
}
return ans;
}
int main()
{
int N,n,i,j;
double ans;
cin>>N;
while(N--)
{
cin>>n;
for(i=1;i<=n;i++)
cin>>e[i].x>>e[i].y;
for(i=1;i<=n;i++)
for(j=i;j<=n;j++)
dist[i][j]=dist[j][i]=dis(e[i],e[j]);
ans=prim(n);
cout<<ans<<endl;
}
return 0;
}