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 ...
随机推荐
- 抽一根烟的时间学会.NET Core 操作RabbitMQ
什么是RabbitMQ? RabbitMQ是由erlang语言开发的一个基于AMQP(Advanced Message Queuing Protocol)协议的企业级消息队列中间件.可实现队列,订阅/ ...
- Java并发编程基础三板斧之Semaphore
引言 最近可以进行个税申报了,还没有申报的同学可以赶紧去试试哦.不过我反正是从上午到下午一直都没有成功的进行申报,一进行申报 就返回"当前访问人数过多,请稍后再试".为什么有些人就 ...
- 剑指 Offer 46. 把数字翻译成字符串 + 动态规划
剑指 Offer 46. 把数字翻译成字符串 Offer_46 题目描述 题解分析 本题的解题思路是使用动态规划,首先得出递推公式如下 dp[i] = dp[i-1]+dp[i-2](如果s[i-1] ...
- Go中定时器实现原理及源码解析
转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com 本文使用的go的源码15.7,需要注意的是由于timer是1.14版本进行改版,但是1. ...
- pandas函数的使用
一.Pandas的数据结构 1.Series Series是一种类似与一维数组的对象,由下面两个部分组成: values:一组数据(ndarray类型) index:相关的数据索引标签 1)Serie ...
- MySQL数据库之一
数据库简介 数据库分类 关系型数据库(SQL):(狭义可以理解为行和列) MySQL,Oracle,Sql Server, DB2 通过表和表之间,行和列之间的关系进行存储 非关系型数据库(NoSQL ...
- vue离开页面销毁滚动事件
methods:{ handleFun(){ /**销毁处理*/ } }, beforeDestroy(){ window.removeEventListener("scroll&qu ...
- LookupError: 'hex' is not a text encoding; use codecs.decode() to handle arbitrary codecs
问题代码: b=b'\x01\x02\x03' x=binascii.b2a_hex(b.decode('hex')[::-1].encode('hex')) python2下是不报错的,因为pyth ...
- 图解 | 原来这就是 IO 多路复用
为了讲多路复用,当然还是要跟风,采用鞭尸的思路,先讲讲传统的网络 IO 的弊端,用拉踩的方式捧起多路复用 IO 的优势. 为了方便理解,以下所有代码都是伪代码,知道其表达的意思即可. Let's go ...
- Oment++ 初学者教程 第4节-将其转变为真实网络
4.1两个以上的节点 现在,我们将迈出一大步:创建几个tic模块并将它们连接到网络中.现在,我们将使它们的工作变得简单:一个节点生成一条消息,其他节点继续沿随机方向扔消息,直到它到达预定的目标节点为止 ...