HDU 4756 Install Air Conditioning(树形dp+MST)
2016-08-18 00:25
323 查看
题目链接:
HDU 4756 Install Air Conditioning
题意:
给n个点的二维坐标,要将这n个点连通,边权就是两点距离,其中0号节点是根,可能会破坏除根之外的任意两点的边(不能建边),要求将这n个点连通的最坏代价?
数据范围:n≤1000
分析:
上面的黑体字是因为原题中有这句话:
But Tom200 is informed that there are so many wires between two specific dormitories that we cannot set a new high-load wire between these two, otherwise it may have potential risks.
其实这道题的意思和HDU 4126 Genghis Khan the Conqueror是一样的,注意到上面的Trick就好了。枚举破坏的边即可。
时间复杂度:O(n2)。
HDU 4756 Install Air Conditioning
题意:
给n个点的二维坐标,要将这n个点连通,边权就是两点距离,其中0号节点是根,可能会破坏除根之外的任意两点的边(不能建边),要求将这n个点连通的最坏代价?
数据范围:n≤1000
分析:
上面的黑体字是因为原题中有这句话:
But Tom200 is informed that there are so many wires between two specific dormitories that we cannot set a new high-load wire between these two, otherwise it may have potential risks.
其实这道题的意思和HDU 4126 Genghis Khan the Conqueror是一样的,注意到上面的Trick就好了。枚举破坏的边即可。
时间复杂度:O(n2)。
#include <stdio.h> #include <string.h> #include <math.h> #include <algorithm> #include <vector> using namespace std; const int MAX_N = 1010; int T, n, K; double dis[MAX_N][MAX_N], way[MAX_N], x[MAX_N], y[MAX_N], dp[MAX_N][MAX_N]; int fa[MAX_N], vis[MAX_N]; vector<int> vec[MAX_N]; double GetDis(int i, int j) { double xx = x[i] - x[j], yy = y[i] - y[j]; return sqrt(xx * xx + yy * yy); } double Prim() { double res = 0; for (int i = 0; i < n; ++i) { fa[i] = vis[i] = 0; way[i] = dis[i][0]; } vis[0] = 1, fa[0] = -1; for (int i = 1; i < n; ++i) { double Min = 1e20; int id; for (int j = 0; j < n; ++j) { if (!vis[j] && way[j] < Min) { Min = way[j]; id = j; } } vis[id] = 1; res += Min; if (fa[id] != -1) { vec[id].push_back(fa[id]); vec[fa[id]].push_back(id); } for (int j = 0; j < n; ++j) { if (!vis[j] && dis[j][id] < way[j]) { way[j] = dis[j][id]; fa[j] = id; } } } return res; } double dfs(int root, int u, int p) { double Min = 1e20; for (int i = 0; i < vec[u].size(); ++i) { int v = vec[u][i]; if (v == p) continue; double tmp = dfs(root, v, u); Min = min(Min, tmp); dp[u][v] = dp[v][u] = min(dp[u][v], tmp); } if (p != -1 && p != root) Min = min(Min, dis[root][u]); return Min; } int main() { scanf("%d", &T); while (T--) { scanf("%d%d", &n, &K); for (int i = 0; i < n; ++i) { vec[i].clear(); scanf("%lf%lf", &x[i], &y[i]); for (int j = 0; j < i; ++j) { dis[i][j] = dis[j][i] = GetDis(i, j); dp[i][j] = dp[j][i] = 1e20; } } double sum = Prim(); for (int i = 0; i < n; ++i) dfs(i, i, -1); double ans = sum; for (int i = 1; i < n; ++i) { for (int j = 1; j < i; ++j) { if (fa[i] == j || fa[j] == i) { ans = max(ans, sum - dis[i][j] + dp[i][j]); } } } printf("%.2lf\n", ans * K); } return 0; }
相关文章推荐
- java实现 聚类算法之MST算法
- 【HDU 5366】The mook jong 详解
- 【HDU 2136】Largest prime factor 详细图解
- 【HDU 1568】Fibonacci 数学公式 详解
- HDU 1568
- HDU1290
- HDU1568(Fobonacci公式)
- HDU ACM Step 2.2.2 Joseph(约瑟夫环问题)
- HDU 1405
- HDU 1297
- hdu 1205
- hdu 2087
- hdu 1016
- HDU 4898 The Revenge of the Princess’ Knight ( 2014 Multi-University Training Contest 4 )
- HDU 5592 ZYB's Premutation 线段树(查找动态区间第K大)
- HDU 5240 Exam (好水的题)
- HDU5237 Base64 大模拟
- HDU 1000
- HDU 1001
- HDU 1016 Prime Ring Problem