hdu4756 最小树+树形dp
题意:
给你一个完全图,让你在上面找到一颗最小树,然后问破坏这个最小树的某一条边后用其他边连接(要求最小)成新的树,然后输出破坏每一条边后最小树中最大的那个.
思路:
先跑出一颗最小树,然后枚举树上的每一条边,当这条边被删除的时候,生成树就被分成了两个集合,然后找到一条最小的能让两个集合相通的替代边,最后输出最大的那个(树形dp优化),下面是我的ac记录
想法错了 求的次小树 WA
Kruskal + 并查集优化 暴力枚举 TLE
Kruskal + 树形DP TLE
Prim + 树形DP AC
哎,这个题目时间卡的太紧了, 这个题目非得强调K是解决稀疏图的,P是解决稠密图的...
(下面的Prim之前没用过,之前用的是K,所以直接百度了个模板,然后写成结构体了,所以整个代码有点乱因为要配合百度来的Prim,自己懒啊,不想再看Prim了,只是记下他的模板了,以后遇到卡稠密图的题再粘过来.)
#include<stdio.h>
#include<string.h>
#include<math.h> #define N (1000 + 100) #define inf 100000000
typedef struct
{
int x ,y;
}NODE; typedef struct
{
int a ,b;
double dis;
}EDGE; typedef struct
{
int to ,next;
}STAR; NODE node[N];
EDGE edge[N*N/2];
STAR E[N*2]; int list[N] ,tot;
double map[N][N];
double dp[N][N]; bool camp(EDGE a ,EDGE b)
{
return a.dis < b.dis;
} void add(int a, int b)
{
E[++tot].to = b;
E[tot].next = list[a];
list[a] = tot; E[++tot].to = a;
E[tot].next = list[b];
list[b] = tot;
} double maxx(double a ,double b)
{
return a > b ? a : b;
} double minn(double a ,double b)
{
return a < b ? a : b;
} double q_dis(double x1 ,double y1 ,double x2 ,double y2)
{
double x = x1 - x2;
double y = y1 - y2;
return sqrt(x * x + y * y);
} double dfs(int p ,int s ,int f)
{
double now = inf;
for(int k = list[s] ;k ;k = E[k].next)
{
int to = E[k].to;
if(to == f) continue;
double tmp = dfs(p ,to ,s);
now = minn(now ,tmp);
dp[s][to] = dp[to][s] = minn(dp[s][to] ,tmp);
}
if(p != f) now = minn(now ,map[p][s]);
return now;
} struct PRIM //从0开始用
{
double d[N];int vis[N];
bool mp[N][N]; //标记最小生成树上的边
double ans;//最小树
int n;//点的个数 记得初始化 ***
double dis[N][N]; // 距离 记得初始化 *****
void prim()
{
for(int i=0;i<n;i++)
{
vis[i]=0;
d[i]=dis[0][i];
}
vis[0]=-1;
ans=0;
memset(mp,0,sizeof(mp));
for(int i=1;i<n;i++)
{
double Min= inf;
int node=-1;
for(int j=0;j<n;j++)
{
if(vis[j]!=-1 && d[j]<Min)
{
node=j;
Min=d[j];
}
} ans+=Min;
mp[vis[node]][node]=mp[node][vis[node]]=1;
add(vis[node],node); // 建树
vis[node]=-1; for(int j=0;j<n;j++)
{
if(vis[j]!=-1 && d[j]>dis[node][j])
{
vis[j]=node;
d[j]=dis[node][j];
}
}
}
}
}P; int main ()
{
int t ,i ,j ,n;
double pre;
scanf("%d" ,&t);
while(t --)
{
scanf("%d %lf" ,&n ,&pre);
for(i = 0 ;i < n ;i ++)
scanf("%d %d" ,&node[i].x ,&node[i].y);
int tmp = 0;
for(i = 0 ;i < n ;i ++)
{
for(j = i ;j < n ;j ++)
{
map[j][i] = map[i][j] = q_dis(node[i].x ,node[i].y ,node[j].x ,node[j].y);
P.dis[i][j] = P.dis[j][i] = map[i][j];
edge[++tmp].a = i;
edge[tmp].b = j;
edge[tmp].dis = map[i][j];
dp[i][j] = dp[j][i] = inf;
}
} P.n = n;
memset(list ,0 ,sizeof(list));
tot = 1;
P.prim();
for(i = 1 ;i <= n ;i ++) dfs(i ,i ,-1);
double T_sum = P.ans;
double ans = T_sum;
for(i = 1 ;i < n ;i ++)
for(j = i + 1 ;j < n ;j ++)
if(P.mp[i][j])
ans = maxx(ans ,T_sum - map[i][j] + dp[i][j]);
printf("%.2lf\n" ,ans * pre);
}
return 0;
}
hdu4756 最小树+树形dp的更多相关文章
- hdu4756 Install Air Conditioning(MST + 树形DP)
题目请戳这里 题目大意:给n个点,现在要使这n个点连通,并且要求代价最小.现在有2个点之间不能直接连通(除了第一个点),求最小代价. 题目分析:跟这题一样样的,唉,又是原题..先求mst,然后枚举边, ...
- hdu4126(MST + 树形dp
题意: 这个题目和hdu4756差不多,是给你一个图,然后是q次改变边的权值,权值只增不减,最后问你每次改变之后的最小树的平均值是多少. 思路:(prim+树形dp) 先跑一边 ...
- 算法进阶面试题05——树形dp解决步骤、返回最大搜索二叉子树的大小、二叉树最远两节点的距离、晚会最大活跃度、手撕缓存结构LRU
接着第四课的内容,加入部分第五课的内容,主要介绍树形dp和LRU 第一题: 给定一棵二叉树的头节点head,请返回最大搜索二叉子树的大小 二叉树的套路 统一处理逻辑:假设以每个节点为头的这棵树,他的最 ...
- BZOJ 4890: [Tjoi2017]城市 树形dp
标签:树形dp,枚举,树的直径 一上来看到这个题就慌了,只想到了 $O(n^3)$ 的做法. 碰到这种题时要一步一步冷静地去分析,观察数据范围. 首先,$n\leqslant 5000$,所以可以先 ...
- poj3417 LCA + 树形dp
Network Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4478 Accepted: 1292 Descripti ...
- COGS 2532. [HZOI 2016]树之美 树形dp
可以发现这道题的数据范围有些奇怪,为毛n辣么大,而k只有10 我们从树形dp的角度来考虑这个问题. 如果我们设f[x][k]表示与x距离为k的点的数量,那么我们可以O(1)回答一个询问 可是这样的话d ...
- 【BZOJ-4726】Sabota? 树形DP
4726: [POI2017]Sabota? Time Limit: 20 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 128 Solved ...
- 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)
题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...
- 树形DP
切题ing!!!!! HDU 2196 Anniversary party 经典树形DP,以前写的太搓了,终于学会简单写法了.... #include <iostream> #inclu ...
随机推荐
- MySQL数据库插入数据出现 ERROR 1526 (HY000): Table has no partition for value xxx
MySQL数据库插入数据出现ERROR 1526 (HY000): Table has no partition for value xxx工作的时候发现无法插入数据,报错:ERROR 1526 (H ...
- 如何快速开发Winform应用系统
在实际的业务中,往往还有很多需要使用Winform来开发应用系统的,如一些HIS.MIS.MES等系统,由于Winform开发出来的系统界面友好,响应快速,开发效率高等各方面原因,还有一些原因是独立的 ...
- Linux下制作Windows启动U盘的工具
Linux下制作Windows启动U盘的工具 很多人说Linux下制作Windwos启动盘要用GRUB4DOS建立引导,其实不用,有专门的工具的,就像Windows下有Rufus制作Linux启动U盘 ...
- docker搭建redis集群和Sentinel,实现故障转移
0.引言 公司开发需要用到redis,虽然有运维自动搭建,还是记录下如何搭建redis集群和Sentinel. 采用的是vagrant虚拟机+docker的方式进行搭建. 搭建思路: 首先是借鉴下其他 ...
- 【RocketMQ源码分析】深入消息存储(1)
最近在学习RocketMQ相关的东西,在学习之余沉淀几篇笔记. RocketMQ有很多值得关注的设计点,消息发送.消息消费.路由中心NameServer.消息过滤.消息存储.主从同步.事务消息等等. ...
- SQLServer 2008快速导出架构和数据脚本
https://jingyan.baidu.com/article/454316ab715218f7a7c03a9d.html
- java关于字符串是否存
1, if('true'.equalsIgnoreCase(response.result as String)); 2, if (scvrsp.toLowerCase().contains(&q ...
- 几大BSD 区别
OpenBSD 侧重于安全,软件包较少,较陈旧,比如 KDE 才 3.5,为了安全舍弃了 sudo 和 linux 兼容层: FreeBSD 是开发者最多用户最多软件包最多的,有 ZFS 和 Linu ...
- WPF 基础 - Binding 的源与路径
1. 源与路径 把控件作为 binding 源与 binding 标记拓展: 控制 Binding 的方向及数据更新: Binding 的路径 Path: 没有路径的 Binding: 为 Bindi ...
- U盘重装系统:手把手教你怎么使用U盘重装系统、清除登录密码
前言 之前讲过<不懂电脑也能自己重装系统,可视化傻瓜式一键重装系统不求人!!!>,这是针对可以正常开机的情况下直接使用浏览器功能重装系统, 那不能正常开机或者忘记密码的怎么办呢? 不慌,今 ...