题目:http://poj.org/problem?id=1751
两种算法思路:https://www.cnblogs.com/PJQOOO/p/3855017.html
方法:
1.普利姆算法(数组大小开小了导致一直wa)
#include<cstdio>
#include<cmath>
#define len 760
#define inf 10000000
using namespace std;
int vis[len],t[len][2],pre[len],n,m,map[len][len],d[len];
int dkr(int x1,int y1,int x2,int y2)
{
return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
}
void prim()
{
for(int i=1;i<=n;i++)
{
vis[i]=0;
d[i]=map[i][1];
pre[i]=1;
}
d[1]=1;
vis[1]=1;
for(int i=1;i<n;i++)
{
int k,t1=inf;
for(int j=1;j<=n;j++) if(vis[j]==0&&d[j]<t1) k=j,t1=d[j];
vis[k]=1;
if(map[pre[k]][k]) printf("%d %d\n",pre[k],k);
for(int j=1;j<=n;j++) if(vis[j]==0&&d[j]>map[k][j]) d[j]=map[k][j],pre[j]=k;
}
}
int main()
{
int a,b;
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d%d",&t[i][0],&t[i][1]);
for(int i=1;i<n;i++)
{
for(int j=i+1;j<=n;j++)
map[i][j]=map[j][i]=dkr(t[i][0],t[i][1],t[j][0],t[j][1]);
map[i][i]=inf;
}
scanf("%d",&m);
while(m--)
{
scanf("%d%d",&a,&b);
map[a][b]=map[b][a]=0;
}
prim();
return 0;
}
2.并查集
#include<cstdio>
#include<algorithm>
#include<cmath>
#define len 750
using namespace std;
int use[len],t[len][2];
struct node
{
int x,y;
double l;
}s[len*400];
int com(node a,node b)
{
return a.l<b.l;
}
int find(int x)
{
return x!=use[x]? use[x]=find(use[x]):x;
}
double dkr(int x1,int y1,int x2,int y2)
{
return sqrt(1.0*(x1-x2)*(x1-x2)+1.0*(y1-y2)*(y1-y2));
}
int main()
{
int n,m,a,b;
scanf("%d",&n);
int k=0;
for(int i=0;i<=n;i++) use[i]=i;
for(int i=1;i<=n;i++) scanf("%d %d",&t[i][0],&t[i][1]);
for(int i=1;i<=n-1;i++)
for(int j=i+1;j<=n;j++)
{
s[k].x=i;
s[k].y=j;
s[k++].l=dkr(t[i][0],t[i][1],t[j][0],t[j][1]);
}
sort(s,s+k,com);
scanf("%d",&m);
while(m--)
{
scanf("%d%d",&a,&b);
int x=find(a),y=find(b);
use[y]=x;
}
for(int i=0;i<k;i++)
{
int x=find(s[i].x),y=find(s[i].y);
if(x!=y)
{
use[y]=x;
printf("%d %d\n",s[i].x,s[i].y);
}
}
return 0;
}