题意:给定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; }