POJ 1751题
//最小生成树:Prim算法实现,不要使用Kruskal算法,否则会出现超时
#include <stdio.h>
#include <math.h>
#include <string.h>
#define nodesize 1001
typedef struct node
{
int x;
int y;
}node; //对于nodes和record的含义不同,nodes指的是点的横纵坐标,record指的是最小生成树中的边
node nodes[nodesize];
node record[nodesize];
double dis[nodesize][nodesize];
double d[nodesize];
bool final[nodesize];
int recordhead[nodesize]; //存储节点的前驱
int N,M;
double distance(int x1,int y1,int x2,int y2)
{
return sqrt(double((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))); //此处别忘了加double
}
void prim()
{
int i,j;
int num=0;
memset(final,0,sizeof(final));
for(i=1;i<N+1;++i)
{
d[i] = dis[1][i];
}
d[1] = 0;
final[1] = true;
for(i=1;i<N+1;++i)
recordhead[i] = 1; //存储i的前驱
int v = 1;
for(i=1;i<N;++i)
{
double min = 999999999;
for(j=1;j<N+1;++j)
{
if(!final[j] && d[j]<min)
{
min = d[j];
v = j;
}
}
final[v] = true;
if((int)min!=0) //如果该道路没有修建
{
num++;
record[num].x = recordhead[v]; //记录最小生成树
record[num].y = v;
}
for(j=1;j<N+1;++j)
{
if(!final[j] && d[j]>dis[v][j])
{
d[j] = dis[v][j];
recordhead[j] = v; //修改前驱
}
}
}
for(i=1;i<num+1;++i)
{
printf("%d %d\n",record[i].x,record[i].y);
}
}
int main()
{
//freopen("1.txt","r",stdin);
int i,j;
scanf("%d",&N);
for(i=1;i<N+1;++i)
{
scanf("%d%d",&nodes[i].x,&nodes[i].y);
}
for(i=1;i<N+1;++i)
{
for(j=1;j<N+1;++j)
{
dis[i][j] = distance(nodes[i].x,nodes[i].y,nodes[j].x,nodes[j].y);
}
}
scanf("%d",&M);
int start,end;
for(i=1;i<M+1;++i)
{
scanf("%d%d",&start,&end);
dis[start][end] = 0; //将已修建的道路的距离设置为0,双向的
dis[end][start] = 0;
}
prim();
return 0;
}