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 ...
随机推荐
- C++类的友元机制说明
下面给出C++类的友元机制说明(对类private.protected成员访问),需要注意的是,友元机制尽量不用或者少用,虽然它会提供某种程度的效率,但会带来数据安全性的问题. 类的友元 友元是C++ ...
- Zeebe服务学习1-简单部署与实现demo
1.Zeebe是什么? Camunda公司研发的工作流引擎Zeebe,目标是对微服务的编排.具体详细介绍可以参考官网:https://zeebe.io/what-is-zeebe/ 2.背景 随着微服 ...
- Cloudam云端携手高校探索云计算在生命科学领域的应用
随着云计算服务和实践的成熟,越来越多的行业对于云计算的需求也日益增加.不同行业的需求与云计算融合,就需要更大的算力支撑.这也意味着,云计算的需求市场日渐扩大,Cloudam云端自主研发的云E算力平台应 ...
- 基于Hi3559AV100 RFCN实现细节解析-(3)系统输入VI分析一 :
下面随笔系列将对Hi3559AV100 RFCN实现细节进行解析,整个过程涉及到VI.VDEC.VPSS.VGS.VO.NNIE,其中涉及的内容,大家可以参考之前我写的博客: Hi3559AV100的 ...
- Codeforces1493D GCD of an Array
题目链接 点我跳转 题目大意 给定一个长度为 \(N\) 的序列 \(A\) 有 \(Q\) 次操作,每次操作给定两个数 \(i\) , \(X\),使得 \(A[i] = A[i] \times X ...
- 通达OA 越权访问-2013/2015版本
漏洞参考 http://wiki.0-sec.org/0day/%E9%80%9A%E8%BE%BEoa/9.html 复现 根据⽹上的通达 OA的源码找这些敏感地址,如: /general/syst ...
- mysql数据库的数据备份,以及开启日志
导出数据: location代表需要保存的数据文件的位置,默认保存在 C:\ProgramData\MySQL\MySQL Server 5.7\Data(Windows10系统位置,其他系统位置自行 ...
- C# 通过ServiceStack 操作Redis——Set类型的使用及示例
ServiceStack 程序集里面没有方法注解,我在这里将注解添加上去,有不当之处,欢迎指正 Console.WriteLine("---Set类型---"); //添加 set ...
- HDU_3949 XOR 【线性基】
一.题目 XOR 二.分析 给定$N$个数,问它的任意子集异或产生的数进行排列,求第K小的数. 构造出线性基$B$后,如果$|B| < N$,那么代表N个数中有一个数是可以由线性基中的其他数异或 ...
- IPFS挖矿硬盘满了会怎样?
IPFS是一个互联网协议,对标现在的HTTP.所以,可以想见未来IPFS有多大的价值.所谓IPFS挖矿,是基于IPFS,挖的是filecoin,称其为filecoin挖矿倒是更为贴切.许多初接触IPF ...