poj 1751 最小生成树

本文介绍了一种使用Prim算法寻找最小生成树的方法,并通过具体代码实现了该算法。文章详细解释了如何通过Prim算法来确定图中各顶点间的最优连接方式,特别关注于已连接边的处理及边权重的计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目的大意就是现在有些已经连接在一起的边,让你在连接其他的N-M条边,让你计算出其他的各条边的情况,问题是我的答案和他那上面的有些顺序不照居然也AC了,不知道是这道题的数据弱还是什么其他的原因,神奇的一道题啊。。


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>

using namespace std;

#define INF 10000000
struct point
{
   int x, y;
};
point city[755],_city[755];
int N, M;
int _min;
int arcs[755][755];
bool vis[755];
int dist[755],disnode[755];
int compare(point a, point b)
{
  return a.x<b.x;
}
int dis(point p0, point p1)
{
    return ((p0.x-p1.x)*(p0.x-p1.x) + (p0.y-p1.y)*(p0.y-p1.y)); 
}
int prim()
{
    scanf("%d",&N);
    for(int i=1; i<=N; i++)
    scanf("%d %d",&city[i].x, &city[i].y);
    for(int i=1; i<=N; i++)
    for(int j=i; j<=N; j++)
    {
      arcs[i][j] = arcs[j][i] = dis(city[i],city[j]);
     // printf("%d ",arcs[i][j]);
    }
    int a, b, rec;
    memset(vis,false,sizeof(vis));
      scanf("%d",&M);
    for(int i=1; i<=M; i++)
    {
    scanf("%d %d", &a, &b);
     arcs[a][b] = arcs[b][a] = 0;  
    }
    for(int i=1; i<=N; i++)
    {
      dist[i] = arcs[1][i];
      disnode[i] = 1;
    }
    vis[1] = true; int t=0;
    for(int i=2; i<=N; i++)
    {
       _min = INF;
       rec = 0;
       for(int j=1; j<=N; j++)
       if(!vis[j]&&dist[j]<_min)
       {
          _min = dist[j];
          rec = j;
       }
       vis[rec] = true;
      if(_min != 0)
      {
      //  printf("%d %d\n", disnode[rec], rec);
      if(disnode[rec]<rec)
       {
        _city[t].x = disnode[rec];
        _city[t].y = rec;
       }
       
       else
       {
        _city[t].x = rec;
        _city[t].y = disnode[rec];
       }
       t++;
      }
       for(int j=1; j<=N; j++)
       if(!vis[j]&&dist[j]>arcs[rec][j])
       {
       dist[j] = arcs[rec][j];
       disnode[j] = rec;
       }
    }
  return t;  
}
int main()
{
int n = prim();
sort(_city,_city+n,compare);
for(int i=0; i<n; i++)
printf("%d %d\n",_city[i].x, _city[i].y);
system("pause");
return 0;
}



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值