题目的大意就是说给你几个点的坐标,并且有几个点之间路是已经修好了的,让你加入其他的边,使得边权和最小,最小生成树的问题,只是初始给了你固定的几条边而已。用prim算法比较好,因为prim算法比较适合稠密图,kruskal算法更适合稀疏图,而这个图每个点之间都要求长度,边比较多。
好了 上代码;
<span style="font-size:14px;">#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;
int dp[1000][1000];
int dup[1000];
int dis[10000];
int vis[1000];
int x[1000],y[1000];
int n;
int prim()
{
int i,next,k;
int count=0;
for(int i=1;i<=n;i++)
{
dis[i]=dp[1][i];
dup[i]=1;//此时是dis存的值全部是1到各个点的距离
}
vis[1]=1;
count++;
while(count<n)
{
int min=0x3f3f3f;
for(i=1;i<=n;i++)
{
if(!vis[i]&&dis[i]<min)
{
min=dis[i];
next=i;
}
}
if(dp[dup[next]][next])
{
printf("%d %d\n",dup[next],next);
}
vis[next]=1;//更新点
count++;
for(i=1;i<=n;i++)
{
if(!vis[i]&&dis[i]>dp[next][i])
{
dis[i]=dp[next][i];
dup[i]=next;//用dup[i]=next表示如果此时是i与next相连
}
}
}
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)
{
scanf("%d %d",&x[i],&y[i]);
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i==j)
dp[i][j]=0;
else
{
dp[i][j]=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
dp[j][i]=dp[i][j];
}
}
}
int m;
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
int x1,x2;
scanf("%d %d",&x1,&x2);
dp[x1][x2]=dp[x2][x1]=0;//直接把给的边权值等于0
}
prim();
}
return 0;
}
</span>