uva10034

题目大意:
给出背上斑点的坐标,求连接这些斑点所用的最少的墨水。

思路:
最小生成树

代码:

#include <iostream>
using namespace std;
#include <cstring>
#include <stdio.h>
#include <cmath>
#include <algorithm>

double x[105],y[105];
double dis[5050];//i,j之间的权值
int flag[5050];//编号
int jihe[5050];//i属于哪个集合
int u[5050],v[5050];
int n,m;
double sum;

int cmp(const int i,const int j) {
    return dis[i] < dis[j] ;
}
int find(int i) {
    if(jihe[i] == i)
        return i;
    else
        return jihe[i] = find(jihe[i]);
// return jihe[i] == i ? i : jihe[i] = find(jihe[i]);
}
void kruskal() {
    sum = 0;
    for(int i = 0; i < n; i++)
        jihe[i] = i;//每一点都属于一个集合
    sort(flag,flag + m, cmp);
    for(int i = 0; i < m; i++) {
        int k = flag[i];
        int x = find(u[k]);
        int y = find(v[k]);
        if(x != y) {
            sum = sum + dis[k];
            jihe[x] = y;
        }
    }
}

int main() {
    int T;
    scanf("%d",&T);
    while(T--) {
        scanf("%d",&n);
    // memset(flag,0,sizeof(flag));
    // memset(jihe,0,sizeof(jihe));
        for(int i = 0; i < n; i++)
            scanf("%lf %lf",&x[i],&y[i]);
        m = 0;
        for(int i = 0 ; i < n; i++) {
            for(int j = i + 1; j < n ; j++)  {
                dis[m] =sqrt((x[i] - x[j]) *(x[i] - x[j]) + (y[i] - y[j]) *(y[i] - y[j]));
                u[m] = i;
                v[m] = j;
                flag[m] = m++;
            }
        }
        kruskal();
        printf("%.2lf\n",sum);
        if(T)
            printf("\n");
    }
    return 0;
}

prim:

#include <iostream>
using namespace std;
#include <stdio.h>
#include <cstring>
#include <cmath>
int n;
double x[105],y[105];
double w[105][105];
int pre[105];
double minCost[105];
int hash[105];
double Prim() {
    double sum = 0;
    memset(hash,0,sizeof(hash));
    hash[1] = 1;
    for(int i = 1; i <= n; i++) {
        minCost[i] = w[1][i];
        pre[i] = 1;
    }
    int u = -1;
    for(int i = 1; i < n; i++) {
        u = -1;
        for(int j = 1; j <= n; j++)
            if(!hash[j]) {
                if(u == -1 || minCost[j] < minCost[u])
                    u = j;
            }//找出权值的最小值
        sum += w[pre[u]][u];
        hash[u] = 1;
        for(int j = 1; j <= n; j++)
            if(!hash[j]) {
                if(minCost[j] > w[u][j]) {
                    minCost[j] = w[u][j];
                    pre[j] = u;
            }//跟u关联的权值如果小于mincost就更新
        }
    }
    return sum;
}
int main() {
    int T;
    scanf("%d",&T);
    while(T--) {
        scanf("%d",&n);
        for(int i = 1; i <= n; i++) {
            scanf("%lf %lf",&x[i],&y[i]);
        }
        memset(w,0,sizeof(w));
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= n; j++) 
                w[i][j] = sqrt((x[i] - x[j]) *(x[i] - x[j]) + (y[i] - y[j]) *(y[i] - y[j]));
        }
        printf("%.2lf\n",Prim());
        if(T)
            printf("\n");
    }
    return 0;
}

你可能感兴趣的:(uva10034)