Arctic Network(POJ 2349)(最小生成树Kruskal)
2016-08-22 17:01
447 查看
http://acm.hust.edu.cn/vjudge/problem/17341
题意:
已知所有村庄的坐标 ( x , y ) ,卫星设备的数量 k 。
问:如何分配卫星设备,才能使各个村庄 之间能直接或间接的通讯,并且 d 的值最 小?求出 d 的最小值。
数据规模:0 <= k <= n<= 500
(From Waterloo University 2002)
题解:假设 d 已知,把所有铺设线路的村庄连接 起来,构成一个图。需要卫星设备的台数 就是图的连通支的个数。d越小,连通支就可能越多。那么,只需找到一个最小的d,使得连通支 的个数小于等于卫星设备的数目。
答案
把整个问题看做一个完全图,村庄就是点, 图上两点之间的边的权值,就是两个村庄 的直线距离。
只需在该图上求最小生成树,d 的最小值即为 第 K 长边!
因为:最小生成树中的最长k-1条长边都去掉 后,正好将原树分成了k 个连通分支,在每 个连通分支上摆一个卫星设备即可(转自北京大学PPT课件)
题意:
已知所有村庄的坐标 ( x , y ) ,卫星设备的数量 k 。
问:如何分配卫星设备,才能使各个村庄 之间能直接或间接的通讯,并且 d 的值最 小?求出 d 的最小值。
数据规模:0 <= k <= n<= 500
(From Waterloo University 2002)
题解:假设 d 已知,把所有铺设线路的村庄连接 起来,构成一个图。需要卫星设备的台数 就是图的连通支的个数。d越小,连通支就可能越多。那么,只需找到一个最小的d,使得连通支 的个数小于等于卫星设备的数目。
答案
把整个问题看做一个完全图,村庄就是点, 图上两点之间的边的权值,就是两个村庄 的直线距离。
只需在该图上求最小生成树,d 的最小值即为 第 K 长边!
因为:最小生成树中的最长k-1条长边都去掉 后,正好将原树分成了k 个连通分支,在每 个连通分支上摆一个卫星设备即可(转自北京大学PPT课件)
#include <iostream> #include <cstdio> #include <string> #include <algorithm> #include <cstring> #include <cmath> #include <vector> #include <map> #include <set> #include <queue> using namespace std; struct point{ int x, y; }; point Point[510]; double Distance(point a, point b) { double d2 = (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y); return sqrt (d2); } struct Edge { int s, e; double w; Edge(int ss, int ee, double ww) : s(ss), e(ee), w(ww) {} Edge() {} bool operator < (const Edge & e1) const { return w < e1.w; } }; vector<Edge> edges; vector<int> parent; int GetRoot(int a) { if (parent[a] == a) return a; parent[a] = GetRoot (parent[a]); return parent[a]; } void Merge(int a, int b) { int p1 = GetRoot (a); int p2 = GetRoot (b); if (p1 == p2) return; parent[p2] = p1; } int main() { #ifndef ONLINE_JUDGE freopen ("in.txt", "r", stdin); #endif // ONLINE_JUDGE int n; scanf ("%d", &n); while (n--) { int s, p; scanf ("%d%d", &s, &p); parent.clear(); edges.clear(); for (int i = 0; i < p; i++) parent.push_back(i); //printf("sdfi"); for (int i = 0; i < p; i++) { scanf ("%d%d", &Point[i].x, &Point[i].y); for (int j = 0; j < i; j++) { //cout << Distance (Point[i], Point[j]) << endl; edges.push_back(Edge(i, j, Distance (Point[i], Point[j]))); edges.push_back(Edge(j, i, Distance (Point[i], Point[j]))); } } sort (edges.begin(), edges.end()); int done = 0; double d = 0; for (int i = 0; i < edges.size(); i++) { if (GetRoot (edges[i].s) != GetRoot (edges[i].e)) { Merge (edges[i].s, edges[i].e); done++; d = edges[i].w; } if (done == p - s) break; } printf ("%.2f\n", d); } return 0; }
相关文章推荐
- POJ2349 Arctic Network(最小生成树,Kruskal)
- POJ 2349 Arctic Network(Kruskal求最小生成树第k条边的长度)
- zoj 1914 || poj 2349 Arctic Network【最小生成树 kruskal && prim】
- poj 2349 Arctic Network 最小生成树第k大边-kruskal
- poj 2349 Arctic Network 【最小生成树-Kruskal】
- Prim最小生成树【poj 2349 Arctic Network;poj 1287 NetWorking】
- 2349 poj &&uva 10369 Arctic Network【最小生成树】
- poj 2349 Arctic Network 最小生成树
- poj 2349 (最小生成树)Arctic Network
- POJ 2349 Arctic Network(最小生成树思想)
- POJ 2349 Arctic Network(最小生成树之Prim)
- poj 2349 Arctic Network(最小生成树的第k大边证明)
- POJ - 2349 Arctic Network (最小生成树分块)
- poj_2349 Kruskal 最小生成树
- POJ_2349_Arctic Network(最小生成树)
- POJ 2349 Arctic Network (最小生成树)
- poj 2349 Arctic Network 最小生成树
- poj-2349 Arctic Network 最小生成树
- POJ 2349 Arctic Network 最小生成树
- poj 2349 Arctic Network 最小生成树,求第k大条边