HDU 4756 Install Air Conditioning(MST + 树形DP)
2014-09-25 23:30
323 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4756
题意:给n个点,现在要使这n个点连通,并且要求代价最小。现在有2个点之间不能直接连通(除了第一个点),求最小代价。
思路:和HDU4126差不多,思路基本借鉴于http://blog.csdn.net/ophunter_lcm/article/details/12030593
考虑次过程的这样一个性质:求某个点i到以点j为根的树的最短距离=min(i到j所有子树的最短距离,i到j的最短距离),那么可以枚举起点i,从i点开始沿着mst的边dfs,每经过一条边,那么这条边可以将n个点分成2部分,一部分含i,另一部分不含i(废话),利用dfs的性质,对于从i出发沿着生成树的边遍历到的每个点,当要离开这个点的时候,保证其所有的子树都已经遍历完毕,那么i到j的子树的最短距离就确定了,那么以到达j的边为割边,i到j这颗子树的最短距离就有了。每一次从i点的dfs表示的是枚举割边后包含i的子树和不包含i的子树之间的最小距离。枚举每个点,就能得到对于所有生成树的边,dp[u][v]表示以(u,v)为割边的两颗子树的最短距离。
题意:给n个点,现在要使这n个点连通,并且要求代价最小。现在有2个点之间不能直接连通(除了第一个点),求最小代价。
思路:和HDU4126差不多,思路基本借鉴于http://blog.csdn.net/ophunter_lcm/article/details/12030593
考虑次过程的这样一个性质:求某个点i到以点j为根的树的最短距离=min(i到j所有子树的最短距离,i到j的最短距离),那么可以枚举起点i,从i点开始沿着mst的边dfs,每经过一条边,那么这条边可以将n个点分成2部分,一部分含i,另一部分不含i(废话),利用dfs的性质,对于从i出发沿着生成树的边遍历到的每个点,当要离开这个点的时候,保证其所有的子树都已经遍历完毕,那么i到j的子树的最短距离就确定了,那么以到达j的边为割边,i到j这颗子树的最短距离就有了。每一次从i点的dfs表示的是枚举割边后包含i的子树和不包含i的子树之间的最小距离。枚举每个点,就能得到对于所有生成树的边,dp[u][v]表示以(u,v)为割边的两颗子树的最短距离。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <cmath> using namespace std; const int N = 1010; const int M = 300010; const int inf = 0x3f3f3f3f; typedef long long ll; int pre , head , flag ; int vis ; double low ; double dis , dp ; struct node { int x, y; } a ; struct M_node { int to, next; } e[M]; int n, m, num; double sum; void build(int s, int t) { e[num].to = t; e[num].next = head[s]; head[s] = num ++; } double Dis(int x1, int y1, int x2, int y2) { return sqrt(1.0 * (x1 - x2) * (x1 - x2) + 1.0 * (y1 - y2) * (y1 - y2)); } void init() { sum = 0; num = 0; memset(flag, 0, sizeof(flag)); memset(vis, 0, sizeof(vis)); memset(head, -1, sizeof(head)); memset(dp, 0, sizeof(dp)); } void prim() { int i, j; for(i = 1; i <= n; i ++) { low[i] = dis[1][i]; pre[i] = 1; } flag[1] = 1; for(i = 1; i < n; i ++) { double Min = inf; int v; for(j = 1; j <= n; j ++) { if(flag[j] == 0 && low[j] < Min) { Min = low[j]; v = j; } } sum += Min; vis[pre[v]][v] = vis[v][pre[v]] = 1; build(v, pre[v]); build(pre[v], v); flag[v] = 1; for(j = 1; j <= n; j ++) { if(flag[j] == 0 && low[j] > dis[v][j]) { low[j] = dis[v][j]; pre[j] = v; } } } } double dfs(int cur, int u, int fa) //用cur更新cur点所在的子树和另外子树的最短距离 { double ans = inf; for(int i = head[u]; ~i; i = e[i].next) //沿着生成树的边遍历 { if(e[i].to == fa) continue; double tmp = dfs(cur, e[i].to, u); //用cur更新的以当前边为割边的两个子树最短距离 ans = min(tmp, ans); //以(fa,u)为割边的2个子树的最短距离 dp[u][e[i].to] = dp[e[i].to][u] = min(tmp, dp[u][e[i].to]); } if(cur != fa) //生成树边不更新 ans = min(ans, dis[cur][u]); return ans; } int main() { int t, i, j; scanf("%d", &t); while(t --) { init(); scanf("%d%d", &n, &m); for(i = 1; i <= n; i ++) scanf("%d%d", &a[i].x, &a[i].y); for(i = 1; i <= n; i ++) for(j = 1; j <= i; j ++) { dp[i][j] = dp[j][i] = inf; if(i == j) dis[i][j] = 0; else dis[i][j] = dis[j][i] = Dis(a[i].x, a[i].y, a[j].x, a[j].y); } prim(); double ans = sum; for(i = 0; i < n; i++) dfs(i, i, -1); for(i = 2; i <= n; i++) { for(j = 2; j < i; j++) if(vis[i][j]) ans = max(ans, sum - dis[i][j] + dp[i][j]); } printf("%.2lf\n", ans * m); } return 0; }
<span style="font-size:18px;"> </span>
相关文章推荐
- HDU 4756 Install Air Conditioning (MST+树形DP)
- MST(prim)+树形dp-hdu-4756-Install Air Conditioning
- HDU - 4756 Install Air Conditioning(树形DP + 最小生成树)
- HDU 4756 Install Air Conditioning(树形dp+MST)
- HDU 4756:Install Air Conditioning (最小生成树最佳替换边,最小生成树+树形dp)
- hdu4756 Install Air Conditioning(MST + 树形DP)
- hdu4756 Install Air Conditioning(MST + 树形DP)
- hdu 4756 Install Air Conditioning
- hdu 4756 Install Air Conditioning
- hdu 4756 Install Air Conditioning(次小生成树变形+树dp)
- HDU 4756 Install Air Conditioning(次小生成树)
- HDU 4756 Install Air Conditioning 块与块,非树边最短路
- hdu 4756 Install Air Conditioning
- HDU 4756 Install Air Conditioning
- MST(prim)+树形dp-hdu-4756-Install Air Conditioning
- hdu 4756 Install Air Conditioning(MST+全边次小树,4级)
- hdu 4126 Genghis Khan the Conqueror hdu 4756 Install Air Conditioning 最小生成树
- HDU 4756 Install Air Conditioning(次小生成树)
- hdu 4756 Install Air Conditioning(2013南京网络赛)
- hdu 4756 Install Air Conditioning(MST+全边次小树,4级)