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;
}

posted @ 2010-04-30 22:29  北海小龙  阅读(265)  评论(0编辑  收藏  举报