uva_10034 Freckles Kruskal (使用并查集) 或Prim

 Kruskal

 

#include <cstdio>
#include <algorithm>
#include <cmath>
#define N 100
#define inf 1e200 
using namespace std;

double w[N * N];
double x[N + 2], y[N +2];

int u[N * N], v[N * N]; 
int p[N + 2]; 
int r[N * N]; 
 
double dis(double x1, double y1, double x2, double y2)
{
       return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
} 

bool cmp(int i, int j)
{
     return w[i] < w[j];
}

int find(int x){return p[x] == x? x: (p[x] = find(p[x])); }
 
int main()
{
    int t;
    int n;
    scanf("%d", &t);
    while (t--)
    {
          scanf("%d", &n);
          for (int i = 0; i <n; i++)
              scanf("%lf %lf", x+i, y+i);
          int m = (n - 1) * (n) / 2;
          int cnt = 0; 
          for (int i = 0;i < n; i++)
               for (int j = i + 1; j < n; j++)
               { 
                     w[cnt] = dis(x[i], y[i], x[j], y[j]);
                     u[cnt] = i, v[cnt] = j;
                     cnt++;
               }
         // if (cnt == m)puts("OK!!"); 
          double ans = 0;
          for (int i = 0; i < m; i++)r[i] = i;
          for (int i = 0; i <  n; i++)p[i] = i;
          sort(r, r+m, cmp); 
          for (int i = 0; i < m; i++)
          {
                 int e = r[i];
                 int x = find(u[e]);
                 int y = find(v[e]);
                 if (x != y){ans += w[e], p[x] = y;}
          }
          printf("%.2f\n", ans);
          if (t)puts(""); 
    }
    return 0;
} 
           
           


 

Prim

 
#include <cstdio>
#include <algorithm>
#include <cmath> 
#include <queue> 
#define N 100
#define inf 1.0e20
using namespace std;

double w[N+ 2] [N + 2];
double x[N + 2], y[N +2];
double key[N   + 2];

double dis(double x1, double y1, double x2, double y2)
{
       return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
} 
struct cmp{
       bool operator()(int x, int y) 
       {  
             return key[x] >  key[y];
       }
};
 
int main()
{
    int t;
    int n;
  //  FILE* fp = fopen("in.txt", "r"); 
    
    scanf("%d", &t);
   //getchar(); 
    while (t--)
    {
          scanf( "%d", &n);
          for (int i = 0; i <n; i++)
                   scanf( "%lf %lf", x+i, y+i);
          for (int i = 0; i <n; i++)
          { 
               for (int j = i + 1; j < n; j++)
                 w[i][j] =  w[j][i] = dis(x[i], y[i], x[j], y[j]);
               w[i][i] = 0;
          }
         // fputs("prim\n", fo);
          for (int i = 0; i <n; i++)
               key[i] = inf; 
          key[0] = 0;
          double ans = 0;
          priority_queue<int, vector<int>, cmp> q ;
          vector<int> v; 
          for (int i = 0; i <n; i++)q.push(i); 
          while (!q.empty())
          {
                int cur = q.top();
                q.pop();
                 
                ans += key[cur];
                 for (int i = 0; i < n; i++)
                { 
                    if (key[i] > w[cur][i])
                    {
                         key[i] = w[cur][i];
                    } 
                }  
                v.clear();
                 while(!q.empty())
                 { 
                      int tmp = q.top();
                      q.pop(); 
                      v.push_back(tmp); 
                 }
                 for (int i = 0; i < v.size(); i++)q.push(v[i]); 
                     
                
          }
          printf("%.2f\n", ans);
          if (t)puts("");
          //getchar(); 
    }
    return 0;
} 
                
                 
           


 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值