HDU 4756 Install Air Conditioning (MST+树形DP)
题意:n-1个宿舍,1个供电站,n个位置每两个位置都有边相连,其中有一条边不能连,求n个位置连通的最小花费的最大值。
析:因为要连通,还要权值最小,所以就是MST了,然后就是改变一条边,然后去找出改变哪条能使得总花费最大,dp[i][j] 表示那条边左边的 i 和右边的 j,
最短距离,然后枚举MST里面的每条边,就能知道哪是最大了,注意 供电站和宿舍之间的边不能考虑的。
代码如下:
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
//#include <tr1/unordered_map>
#define freopenr freopen("in.txt", "r", stdin)
#define freopenw freopen("out.txt", "w", stdout)
using namespace std;
//using namespace std :: tr1; typedef long long LL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const double inf = 0x3f3f3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 1e3 + 5;
const LL mod = 10000000000007;
const int N = 1e6 + 5;
const int dr[] = {-1, 0, 1, 0, 1, 1, -1, -1};
const int dc[] = {0, 1, 0, -1, 1, -1, 1, -1};
const char *Hex[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
inline LL gcd(LL a, LL b){ return b == 0 ? a : gcd(b, a%b); }
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline int Min(int a, int b){ return a < b ? a : b; }
inline int Max(int a, int b){ return a > b ? a : b; }
inline LL Min(LL a, LL b){ return a < b ? a : b; }
inline LL Max(LL a, LL b){ return a > b ? a : b; }
inline bool is_in(int r, int c){
return r >= 0 && r < n && c >= 0 && c < m;
}
struct Point{
double x, y;
};
struct Edge{
int to, next;
};
Edge edge[maxn<<1];
Point a[maxn];
double dist[maxn][maxn], lowc[maxn], dp[maxn][maxn];
bool vis[maxn], is_tree[maxn][maxn];
int pre[maxn], head[maxn];
int cnt;
double sum, ans; double Distan(const Point& lhs, const Point& rhs){
return sqrt((lhs.x - rhs.x) * (lhs.x - rhs.x) + (lhs.y - rhs.y) * (lhs.y - rhs.y));
} void add(int u, int v){
edge[cnt].to = v;
edge[cnt].next = head[u];
head[u] = cnt++;
} void Prim(){
sum = 0.0;
memset(vis, false, sizeof vis);
memset(pre, 0, sizeof pre);
for(int i = 1; i < n; ++i) lowc[i] = dist[0][i];
vis[0] = true; for(int i = 1; i < n; ++i){
double minc = inf;
int p = -1;
for(int j = 0; j < n; ++j)
if(!vis[j] && minc > lowc[j]) minc = lowc[j], p = j;
sum += minc;
vis[p] = true;
add(p, pre[p]);
add(pre[p], p);
for(int j = 0; j < n; ++j)
if(!vis[j] && lowc[j] > dist[p][j])
lowc[j] = dist[p][j], pre[j] = p;
}
} double dfs(int u, int fa, int root){
double ans = fa == root ? inf : dist[root][u];
for(int i = head[u]; ~i; i = edge[i].next){
int v = edge[i].to;
if(v == fa) continue;
double tmp = dfs(v, u, root);
ans = min(ans, tmp);
dp[u][v] = dp[v][u] = min(dp[u][v], tmp);
}
return ans;
} void dfs1(int u, int fa){
for(int i = head[u]; ~i; i = edge[i].next){
int v = edge[i].to;
if(v == fa) continue;
if(fa) ans = max(ans, sum-dist[u][v]+dp[u][v]);
dfs1(v, u);
}
} int main(){
int T; cin >> T;
while(T--){
scanf("%d %d", &n, &m);
for(int i = 0; i < n; ++i) scanf("%lf %lf", &a[i].x, &a[i].y);
for(int i = 0; i < n; ++i)
for(int j = i+1; j < n; ++j)
dist[i][j] = dist[j][i] = Distan(a[i], a[j]); cnt = 0;
memset(head, -1, sizeof head);
Prim(); for(int i = 0; i < n; ++i)
for(int j = 0; j < n; ++j) dp[i][j] = inf;
for(int i = 0; i < n; ++i) dfs(i, -1, i); ans = sum;
dfs1(0, 0);
ans *= m * 1.0;
printf("%.2f\n", ans);
}
return 0;
}
HDU 4756 Install Air Conditioning (MST+树形DP)的更多相关文章
- hdu4756 Install Air Conditioning(MST + 树形DP)
题目请戳这里 题目大意:给n个点,现在要使这n个点连通,并且要求代价最小.现在有2个点之间不能直接连通(除了第一个点),求最小代价. 题目分析:跟这题一样样的,唉,又是原题..先求mst,然后枚举边, ...
- HDU 4756 Install Air Conditioning(次小生成树)
题目大意:给你n个点然后让你求出去掉一条边之后所形成的最小生成树. 比較基础的次小生成树吧. ..先prime一遍求出最小生成树.在dfs求出次小生成树. Install Air Conditioni ...
- hdu 4756 Install Air Conditioning
非正规做法,一个一个的暴,减一下枝,还得采用sort,qsort居然过不了…… #include <cstdio> #include <cmath> #include < ...
- Install Air Conditioning HDU - 4756(最小生成树+树形dp)
Install Air Conditioning HDU - 4756 题意是要让n-1间宿舍和发电站相连 也就是连通嘛 最小生成树板子一套 但是还有个限制条件 就是其中有两个宿舍是不能连着的 要求所 ...
- HDU 1520.Anniversary party 基础的树形dp
Anniversary party Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
- HDU 3586 Information Disturbing(二分+树形dp)
http://acm.split.hdu.edu.cn/showproblem.php?pid=3586 题意: 给定一个带权无向树,要切断所有叶子节点和1号节点(总根)的联系,每次切断边的费用不能超 ...
- HDU 5682 zxa and leaf 二分 树形dp
zxa and leaf 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5682 Description zxa have an unrooted t ...
- HDU 6201 2017沈阳网络赛 树形DP或者SPFA最长路
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6201 题意:给出一棵树,每个点有一个权值,代表商品的售价,树上每一条边上也有一个权值,代表从这条边经过 ...
- hdu 4612 Warm up 双连通+树形dp思想
Warm up Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others) Total S ...
随机推荐
- hadoop Partiton中的字符串Hash函数改进
最近的MapReduce端的Partition根据map生成的Key来进行哈希,导致哈希出来的Reduce端处理任务数量非常不均匀,有些Reduce端处理的数据量非常小(几分钟就执行完成,而最后的pa ...
- OD 实验(五) - 对 PE 结构的简单分析
载入程序,按 Alt+M 查看内存空间 双击进入程序的 PE 头 这些为 DOS 环境下才会运行的 这个执行 PE 的地址,PE 结构的偏移地址为 C0 找到这个地址 以 PE 开头 SizeOfCo ...
- Julia - 函数的定义
Julia 中的函数是将一系列参数组成的元组映设到一个返回值的对象 Julia 中定义函数的基本语法为: julia> function f(x, y) x + y end f (generic ...
- 跟我一起学kafka(二)
kafka安装到linux服务器中的情况较多,但是我们现在在学习当中,所以可以拿windows先试试手.要想学kafk那么必然要做一件事就是安装好kafka,下面我讲详细得windows下安装kafk ...
- nginx代理socket tcp/udp
准备一台linux服务器.nginx官网:http://nginx.org/ .在网上搜到大致用的是 ngx_stream_core_module 这个模块,这里你也可以关注一下官方文档中的其他模块都 ...
- 1、svn架设、基本命令
SVN是Subversion的简称,是一个开放源代码的版本控制系统.是一项十分基础,必须能够熟练使用的工具.Apache网站:https://subversion.apache.org/ 采用C/S模 ...
- angularjs之向下一个页面传参
原理: 1.在a标签跳转时,连接后增加一个参数值 2.在路由中接收 3.在控制器中接收 实现: 1.<a href="#/list/{{val.id}}"> 2.在js ...
- C#并口操作
using System;using System.Runtime.InteropServices;public class PortAccess { [DllImport("inpout3 ...
- delphi BLE 后台
http://codeverge.com/embarcadero.delphi.ios/
- VS2015编译VLC2.2.1(under WIN7-64)<转>
概述: 感谢https://github.com/sunqueen/vlc-2.2.1.32-2013 这个工程,我的工作基本上都是基于它,我只是觉得他的工程设置不够清晰,重新做了一次.区别在于我的工 ...