hdu4463Prim简单变形
最小生成树Prim算法的简单变形,Prim算法就是贪心的思想,从任一点开始,依次选择离已知点最近的点扩展,那么这题只要初始的时候把给出的两点加到已知点中即可。
/* * hdu4463/win.cpp * Created on: 2012-11-17 * Author : ben */ #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <iostream> #include <algorithm> #include <queue> #include <set> #include <map> #include <stack> #include <string> #include <vector> #include <deque> #include <list> #include <functional> #include <numeric> #include <cctype> using namespace std; /** * 普里姆算法求最小生成树。map存储图的邻接矩阵。 * N为图的顶点数 * 返回最小生成树的权值,返回-1表示图不连通 * typec可以是int、float、double等类型 */ typedef double typec; const int MAXN = 60; const typec INF = 0x7fffffff; typec graph[MAXN][MAXN]; int N, p, q; typec MST_Prim() { typec lowcost[MAXN]; int i, j, k; typec minc, ret = 0; copy(graph[p], graph[p] + N, lowcost); lowcost[q] = lowcost[p] = -INF; ret += graph[p][q]; for(int j = 0; j < N; j++) { if(lowcost[j] > graph[q][j]) { lowcost[j] = graph[q][j]; } } for(i = 2; i < N; i++) { minc = INF; for(j = 0; j < N; j++) { if(lowcost[j] > -INF && lowcost[j] < minc) { minc = lowcost[j]; k = j; } } if(minc == INF) { return -1; } ret += minc; lowcost[k] = -INF; for(j = 0; j < N; j++) { if(lowcost[j] > graph[k][j]) { lowcost[j] = graph[k][j]; } } } return ret; } typedef pair<int, int> MyPoint; inline double mydis(const MyPoint &p1, const MyPoint &p2) { return sqrt((p1.first - p2.first) * (p1.first - p2.first) + (p1.second - p2.second) * (p1.second - p2.second)); } void build_graph() { int a, b; scanf("%d%d", &p, &q); p--, q--; vector<pair<int, int> > g; for(int i = 0; i < N; i++) { scanf("%d%d", &a, &b); g.push_back(make_pair(a, b)); } for(int i = 0; i < N; i++) { graph[i][i] = 0; for(int j = i + 1; j < N; j++) { graph[i][j] = graph[j][i] = mydis(g[i], g[j]); } } } int main() { #ifndef ONLINE_JUDGE freopen("data.in", "r", stdin); #endif while(scanf("%d", &N) == 1 && N > 0) { build_graph(); printf("%.2f\n", MST_Prim()); } return 0; }