HDU 4463 Outlets (最小生成树)

题意:给定n个点坐标,并且两个点已经连接,但是其他的都没有连接,但是要找出一条最短的路走过所有的点,并且路线最短。

析:这个想仔细想想,就是应该是最小生成树,把所有两点都可以连接的当作边,然后按最小生成树,写就OK了。

代码如下:

#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
using namespace std ;

typedef long long LL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const double inf = 0x3f3f3f3f3f3f3f;
const double eps = 1e-8;
const int maxn = 1000 + 5;
const int dr[] = {0, 0, -1, 1};
const int dc[] = {-1, 1, 0, 0};
int p, q, n;
int x[55], y[55];
int f[55];
int Find(int x){ return x == f[x] ? x : f[x] = Find(f[x]); }
struct node{
    int u, v;
    double d;
    bool operator < (const node &p) const{
        return d < p.d;
    }
};
node a[55*55];

double dist(int i, int j){
    return 1.0*(x[i] - x[j]) * (x[i] - x[j]) + 1.0*(y[i] - y[j]) * (y[i] - y[j]);
}

int main(){
    while(scanf("%d", &n) == 1 && n){
        scanf("%d %d", &p, &q);
        if(p > q) swap(p, q);
        for(int i = 1; i <= n; ++i){
            scanf("%d %d", &x[i], &y[i]);
            f[i] = i;
        }
        int cnt = 0;
        double ans = 0.0;
        for(int i = 1; i <= n; ++i)
            for(int j = i+1; j <= n; ++j){
                //if(i == j)  continue;
                if(i == p && j == q){
                    int x = Find(p);
                    int y = Find(q);
                    f[y] = x;
                    ans += sqrt(dist(p, q));
                    continue;
                }
                a[cnt].u = i;
                a[cnt].v = j;
                a[cnt++].d = sqrt(dist(i, j));
            }
        sort(a, a+cnt);

        for(int i = 0; i < cnt; ++i){
            int x = Find(a[i].u);
            int y = Find(a[i].v);
            if(x != y){
                f[y] = x;
                ans += a[i].d;
            }
        }
        printf("%.2lf
", ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/dwtfukgv/p/5750603.html