Luogu P7276 送给好友的礼物 题解
我们充分发扬人类智慧。
首先分析性质,如果一个有草莓的节点子树中存在有草莓的节点,那么我们就直接不管这个有草莓的节点,因为首先子树内的草莓已经会遍历这个点。
另外,根据 P3320 [SDOI2015] 寻宝游戏 的结论,一个人肯定是按照 DFS 序大小遍历它需要遍历的草莓节点。
注意到 \(n\le451\),考虑模拟退火。每次随机交换遍历草莓的顺序,再把序列划分为前后两个集合分别给两个人走,取最大值,可以得到 \(77\) 分。
注意到这么做是极其不合理的,因为排序之后对答案影响较大的是每个点的 DFS 序而不是如何分配,于是我们模拟退火随机打乱出边,就可以获得 \(100\) 分的好成绩。
#include <bits/stdc++.h>
using namespace std;
struct val
{
int v,p;
}w[500];
int n,m,u,v,h[500],a[500],c[500],f[500],b[500],d[500][500],dfn[500],ans=1e9,cnt=0,dfc=0;
vector<int>s[500],tmp[500];
mt19937 rd(time(0));
bool cmp(struct val a,struct val b)
{
return a.p<b.p;
}
void dfs1(int x,int fa)
{
for(int i=0;i<s[x].size();i++)
if(s[x][i]!=fa)dfs1(s[x][i],x),c[x]|=c[s[x][i]],f[x]|=c[s[x][i]];
}
void dfs2(int x,int fa,vector<int>s[])
{
dfn[x]=++dfc;
for(int i=0;i<s[x].size();i++)
if(s[x][i]!=fa)dfs2(s[x][i],x,s);
}
int cal(vector<int>s[])
{
dfc=0,dfs2(1,0,s);
for(int i=1;i<=m;i++)w[i].v=a[i],w[i].p=dfn[a[i]];
sort(w+1,w+m+1,cmp);
int la=0,ra=d[1][w[1].v]+d[w[m].v][1],mi=1e9,pr=1e9;
for(int i=1;i<m;i++)ra+=d[w[i].v][w[i+1].v];
mi=ra;
for(int i=1;i<m;i++)
{
la=d[1][w[1].v]+d[w[i].v][1];
for(int j=1;j<i;j++)la+=d[w[j].v][w[j+1].v];
ra=d[1][w[i+1].v]+d[w[m].v][1];
for(int j=i+1;j<m;j++)ra+=d[w[j].v][w[j+1].v];
if(max(la,ra)>pr)break;
mi=min(mi,max(la,ra)),pr=max(la,ra);
}
return mi;
}
void sa()
{
double t=2e5,k=0.99;
while(t>=1e-5)
{
if((double)clock()/CLOCKS_PER_SEC>3.5)return;
int c=t/1000.0*(double)m+1,del=0,now=0;
for(int i=1;i<=n;i++)tmp[i]=s[i];
for(int i=1;i<=c;i++)
{
int x=rd()%n+1;
shuffle(s[x].begin(),s[x].end(),rd);
}
now=cal(s),del=now-cal(tmp),ans=min(ans,now);
if(del>=0)
{
double p=exp(-del/t);
if((double)rd()/UINT_MAX>=p)
for(int i=1;i<=m;i++)s[i]=tmp[i];
}
t*=k;
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(i!=j)d[i][j]=1e9;
else d[i][j]=0;
for(int i=1;i<=n-1;i++)scanf("%d%d",&u,&v),d[u][v]=d[v][u]=1,s[u].push_back(v),s[v].push_back(u);
for(int i=1;i<=m;i++)scanf("%d",&a[i]),c[a[i]]=1;
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
dfs1(1,0),cnt=0;
for(int i=1;i<=m;i++)
if(!f[a[i]])a[++cnt]=a[i];
m=cnt;
for(int i=1;i<=n;i++)c[i]=0;
for(int i=1;i<=m;i++)c[a[i]]=1;
while((double)clock()/CLOCKS_PER_SEC<3.5)sa();
printf("%d\n",ans);
return 0;
}
Luogu P7276 送给好友的礼物 题解的更多相关文章
- hpuoj--校赛--送给新生的礼物(水题)
问题 A: 感恩节KK专场--送给新生的礼物 时间限制: 1 Sec 内存限制: 128 MB 提交: 631 解决: 187 [提交][状态][讨论版] 题目描述 学长KK要送给学弟学妹们礼物, ...
- BZOJ4827:[AH2017/HNOI2017]礼物——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4827 https://www.luogu.org/problemnew/show/P3723 题面 ...
- 洛谷P5364 [SNOI2017]礼物 题解
传送门 /* 热情好客的小猴子请森林中的朋友们吃饭,他的朋友被编号为 1∼N,每个到来的朋友都会带给他一些礼物:大香蕉.其中,第一个朋友会带给他 11 个大香蕉,之后,每一个朋友到来以后,都会带给他之 ...
- P7276-送给好友的礼物【dp】
正题 题目链接:https://www.luogu.com.cn/problem/P7276?contestId=39577 题目大意 \(n\)个点的一棵树,\(k\)个关键点,两个人从根出发分别走 ...
- 【luogu P1955 [NOI2015]程序自动分析】 题解
题目链接:https://www.luogu.org/problemnew/show/P1955 并查集操作,1e9要离散化,数组要开大一些,操作前先执行合并操作 样例好毒啊(全是排好序的) #inc ...
- 【luogu P2195 HXY造公园】 题解
题目链接:https://www.luogu.org/problemnew/show/P2195 fir.吐槽题目(省略1w字 sec.考虑对一个森林的维护,每棵树用并查集维护. 操作1:输出当前查询 ...
- 【luogu P1073 最优贸易】 题解
题目链接:https://www.luogu.org/problemnew/show/P1073 对于状态量相互影响的题目,分层图是个不错的想法. 考虑在题目中分为: 不交易: 直接从1到n出去,为0 ...
- 【luogu P3393 逃离僵尸岛】 题解
题目链接:https://www.luogu.org/problemnew/show/P3393 被占领的点可以先连在一个点上然后只需要对这一个点bfs一遍就可以求所有的危险点 #include &l ...
- 【luogu P4017 最大食物链计数】 题解
题目链接:https://www.luogu.org/problemnew/show/P4017 DAG + DP #include <queue> #include <cstdio ...
- 【luogu P1351 联合权值】 题解
题目链接:https://www.luogu.org/problemnew/show/P1351 做了些提高组的题,不得不说虽然NOIP考察的知识点虽然基本上都学过,但是做起题来还是需要动脑子的. 题 ...
随机推荐
- 测试工作中用到的Redis命令
由于项目测试的需要,经常需要连接Redis数据库修改某些键值,无奈最近Redis的客户端连接工具使用不了 只有使用命令行来操作了,现总结如下: 1.远程连接Redis redis-cli -h hos ...
- AbstractAutoProxyCreator#postProcessBeforeInstantiation
一.定义 postProcessBeforeInstantiation 是 Spring AOP 动态代理的核心扩展点,通过提前创建代理对象优化性能,并支持丰富的自定义逻辑(如事务.安全) 二.代码分 ...
- 第十五届蓝桥杯javaA组 砍柴 (两种写法)详解
参考资料 原题链接砍柴 - 蓝桥云课 (lanqiao.cn) 区间质数搜索--埃拉托斯特尼筛法和欧拉筛法-CSDN博客 思路 质数筛 + 二分 + 博弈 + 状态机(只因bushi) $$ 状态转移 ...
- 🎀抓包工具安装-Charles
简介 Charles 作为一个 HTTP 代理/HTTP 监视器/反向代理工具,允许开发者查看他们的计算机与互联网之间的所有 HTTP 和 HTTPS 通信.工作原理是基于 HTTP 代理的概念,它充 ...
- 等待元素加载出来后再执行下一步的方法(execute javascript指令的用法)
上图,会员修改参数后,提示修改成功,弹出层会暂时冻结页面,导致"会员"菜单不可点击 除了使用sleep加等待时间的方法解决,本教程用"execute javascript ...
- Sentinel源码—4.FlowSlot实现流控的原理
大纲 1.FlowSlot根据流控规则对请求进行限流 2.FlowSlot实现流控规则的快速失败效果的原理 3.FlowSlot实现流控规则中排队等待效果的原理 4.FlowSlot实现流控规则中Wa ...
- Spring 如何解决循环依赖?
Spring通过三级缓存机制来解决单例Bean的Setter或字段注入类型的循环依赖问题.以下是Spring解决循环依赖的核心流程: 1. 三级缓存介绍 Spring容器为了解决循环依赖,维护了以下三 ...
- 《OKR》| 聚焦小目标, 成就大梦想
今天想和大家分享的书籍是 <每个人的 OKR>. 恰好我司也是采用 OKR 结合 KPI 的方式进行目标和绩效管理, 在实践中通过放大目标的功能, 缩小行动的自由, 聚焦在单一方向的机制, ...
- openjdk8下载地址(附赠)
openjdk下载地址:https://jdk.java.net/ (文末已经为大家下好了,放在网盘里) 进去后点8,win. 安装好后,使用java -version命令如下: 成功安装openjd ...
- ElementPlus插件的安装和使用
ElementPlus插件安装和使用 npm install element-plus --save src/main.ts新增 // 关键节点:全局注册 Element Plus,包含样式 impo ...