博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hdu4756 Install Air Conditioning(MST + 树形DP)
阅读量:7079 次
发布时间:2019-06-28

本文共 2309 字,大约阅读时间需要 7 分钟。

题目大意:给n个点,现在要使这n个点连通,并且要求代价最小。现在有2个点之间不能直接连通(除了第一个点),求最小代价。

题目分析:先求mst,然后枚举边,对于生成树上的边替换,用树形dp O(N^2)求出每条生成树边的最小替代边。然后替换后的最大值。

详情请见代码:

 

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;const int N = 1005;const int M = 3000005;const int inf = 0x3f3f3f3f;const double eps = 1e-6;const double PI = acos(-1.0);typedef __int64 ll;double dis[N][N];double dp[N][N];bool used[N][N];bool flag[N];double lowcost[N];int pre[N],head[N];struct node{ int x,y;}pt[N];struct nd{ int to,next;}e_mst[M];int n,m,num;double B;void build(int s,int e){ e_mst[num].to = e; e_mst[num].next = head[s]; head[s] = num ++;}double getdis(int x1,int y1,int x2,int y2){ return sqrt((double)(x1 - x2) * (double)(x1 - x2) + (double)(y1 - y2) * (double)(y1 - y2));}void prim(){ B = 0; int i,j; memset(flag,false,sizeof(flag)); for(i = 1;i <= n;i ++) { lowcost[i] = dis[1][i]; pre[i] = 1; } flag[1] = true; for(i = 1;i < n;i ++) { double Min = 100000000.0; int v; for(j = 1;j <= n;j ++) { if(flag[j] == false && lowcost[j] < Min) { Min = lowcost[j]; v = j; } } B += Min; used[pre[v]][v] = used[v][pre[v]] = true; build(v,pre[v]); build(pre[v],v); flag[v] = true; for(j = 1;j <= n;j ++) { if(flag[j] == false && lowcost[j] > dis[v][j]) { lowcost[j] = dis[v][j]; pre[j] = v; } } }}double dfs(int cur,int u,int fa){ double ret = inf; for(int i = head[u];~i;i = e_mst[i].next) { if(e_mst[i].to == fa) continue; double tmp = dfs(cur,e_mst[i].to,u); ret = min(tmp,ret); dp[u][e_mst[i].to] = dp[e_mst[i].to][u] = min(tmp,dp[u][e_mst[i].to]); } if(cur != fa) ret = min(ret,dis[cur][u]); return ret;}int main(){ int t,i,j; scanf("%d",&t); while(t --) { scanf("%d%d",&n,&m); for(i = 1;i <= n;i ++) scanf("%d%d",&pt[i].x,&pt[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] = getdis(pt[i].x,pt[i].y,pt[j].x,pt[j].y); } memset(used,false,sizeof(used)); memset(head,-1,sizeof(head)); num = 0; prim(); double ans = B; for(i = 0;i < n;i ++) dfs(i,i,-1); for(i = 2;i <= n;i ++) { for(j = 2;j < i;j ++) { if(used[i][j] == true) { ans = max(ans,B-dis[i][j]+dp[i][j]); } } } printf("%.2lf\n",ans*m); } return 0;}//718MS 17100K

 

 

转载地址:http://bfvml.baihongyu.com/

你可能感兴趣的文章
iphone:UISplitView
查看>>
一种简单的数据库性能测试方法
查看>>
使用 Spring 3 MVC HttpMessageConverter 功能构建 RESTful web 服务
查看>>
滚动页面
查看>>
Android日志打印类LogUtils,能够定位到类名,方法名以及出现错误的行数并保存日志文件...
查看>>
Android 监听 WiFi 开关状态
查看>>
Win7系统中哪些服务可以关闭?
查看>>
linux环境中设置jacoco覆盖率
查看>>
使用 Google Cloud 上的 tf.Transform 对 TensorFlow 管道模式进行预处理
查看>>
跳表在手天下我有之ConcurrentSkipListMap
查看>>
一篇文章,从源码深入详解ThreadLocal内存泄漏问题
查看>>
PHP算法:一个数字平分为N份,并且总值相等
查看>>
linux/unix编程手册-1_5
查看>>
Mac OS 解决 /usr/bin/sudo must be owned by uid 0 问题
查看>>
第5条:避免创建不必要的对象
查看>>
使用UltraISO制作U盘启动盘
查看>>
过滤器第二篇【编码、敏感词、压缩、转义过滤器】
查看>>
半小时轻松玩转WebGL滤镜技术系列(一)
查看>>
实现一个可管理、增发、兑换、冻结等高级功能的代币
查看>>
【vue源码篇】filter源码详解
查看>>