正题

题目链接:https://www.luogu.com.cn/problem/P7443?contestId=41429


题目大意

\(n\)个点的一棵有根树,两个人从一号点开始进行有向图博弈。

告诉你Alice是先手还是后手,然后你可以选择加一条链接\((u,v)\)的有向边,权值为\(A\times a_u+B\times a_v\)。求最小权值使得第一个人获胜。(如果死循环则无法获胜)

\(1\leq T\leq 2\times 10^3,2\leq n\leq 2\times 10^5,\sum n\leq 5\times 10^6,1\leq a_i,A,B\leq 10^9\)


解题思路

先考虑没有加边情况的胜负。定义\(1\)为先手必败状态,那么所有叶子都是\(1\)。然后每个节点是所有子节点的或值再异或\(1\)。

那么如果已经必胜就是\(0\)了,否则我们需要改变一号节点的状态。

先考虑加一条返祖边的影响,首先这条边肯定是加在Alice行动的节点上,否则Bob可以选择不走。

而且\(v\)肯定得是先手必败的局面,否则没有意义。然后如果\(v\)是先手必败的话,那么Bob显然还是可以往之前的路径走,如果走到\(u\)节点时是Alice移动那么状态不会改变,否则Bob可以继续走返祖边造成死循环。所以返祖边不能影响状态。

然后考虑翻转一个点的状态需要做什么。

如果这个点是先手必败,那么我们只需要找到另一个先手必败的节点连接过去或者翻转子节点的状态就可以翻转该节点的状态。

如果这个点是先手必胜,那么如果子节点中有两个或以上的先手必败那么该节点无法翻转,否则翻转那个先手必败的节点即可。

那么现在我们需要解决寻找除了该节点到根的路径上的点中权值最小的先手必败节点权值。

用优先队列的话会\(TLE\),所以我们考虑其他方法,我们对于每个节点记录一下子树中最大的先手必败节点权值,然后每次向下递归的时候就取所有除了递归子树以外的子节点子树丢进最小值就好了。

这个记录一个次大值和最大值就可以实现。

时间复杂度\(O(\sum n)\)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<queue>
#define ll long long
using namespace std;
const ll N=2e5+10;
struct node{
ll to,next;
}a[N];
ll T,n,m,t,A,B,tot,w[N],fa[N],z[N];
ll ls[N],f[N],s[N],ans;
ll read(){
ll x=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-f;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
return x*f;
}
void addl(ll x,ll y){
a[++tot].to=y;
a[tot].next=ls[x];
ls[x]=tot;return;
}
void dfs(ll x){
f[x]=s[x]=0;z[x]=1e9+7;
for(ll i=ls[x];i;i=a[i].next){
ll y=a[i].to;
dfs(y);f[x]|=f[y];s[x]+=f[y];
z[x]=min(z[x],z[y]);
}
f[x]^=1;
if(f[x])z[x]=min(z[x],w[x]);
return;
}
void dp(ll x,ll mins){
ll c=mins,zc=mins;
for(ll i=ls[x];i;i=a[i].next){
ll y=a[i].to;
if(z[y]<c)zc=c,c=z[y];
else if(z[y]<zc)zc=z[y];
}
if(f[x]){
for(ll i=ls[x];i;i=a[i].next)
dp(a[i].to,(z[a[i].to]==c)?zc:c);
if(c!=1e9+7)ans=min(ans,w[x]*A+c*B);
}
else if(s[x]==1){
for(ll i=ls[x];i;i=a[i].next)
if(f[a[i].to])dp(a[i].to,(z[a[i].to]==c)?zc:c);
}
}
signed main()
{
T=read();
while(T--){
n=read();t=read();A=read();B=read();
for(ll i=1;i<=n;i++)ls[i]=0;tot=0;
for(ll i=2;i<=n;i++)fa[i]=read(),addl(fa[i],i);
for(ll i=1;i<=n;i++)w[i]=read();
dfs(1);
if(f[1]^t^1){puts("0");continue;}
else{
ans=3e18;dp(1,1e9+7);
if(ans==3e18) puts("-1");
else printf("%lld\n",ans);
}
}
}

P7443-加边【博弈论】的更多相关文章

  1. 博弈论入门小结 分类: ACM TYPE 2014-08-31 10:15 73人阅读 评论(0) 收藏

    文章原地址:http://blog.csdn.net/zhangxiang0125/article/details/6174639 博弈论:是二人或多人在平等的对局中各自利用对方的策略变换自己的对抗策 ...

  2. 博弈论之Nim

    博弈论(一):Nim游戏 重点结论:对于一个Nim游戏的局面(a1,a2,...,an),它是P-position当且仅当a1^a2^...^an=0,其中^表示位异或(xor)运算. Nim游戏是博 ...

  3. 博弈论中的Nim博弈

    瞎扯 \(orzorz\) \(cdx\) 聚聚给我们讲了博弈论.我要没学上了,祝各位新年快乐.现在让我讲课我都不知道讲什么,我会的东西大家都会,太菜了太菜了. 马上就要回去上文化课了,今明还是收下尾 ...

  4. 博弈论简单入门sb总结

    博弈论简单入门sb总结 下午讲博弈论.没预习,GG. 整个下午都在学. 0 有一堆共n个石子,两个人轮流取石子,每个人一次可以取1到k个,取到最后一个石子的人胜利. 小学生都会的sb题.若k+1|n, ...

  5. 【uoj#51】[UR #4]元旦三侠的游戏 博弈论+dp

    题目描述 给出 $n$ 和 $m$ ,$m$ 次询问.每次询问给出 $a$ 和 $b$ ,两人轮流选择:将 $a$ 加一或者将 $b$ 加一,但必须保证 $a^b\le n$ ,无法操作者输,问先手是 ...

  6. [您有新的未分配科技点]博弈论进阶:似乎不那么恐惧了…… (SJ定理,简单的基础模型)

    这次,我们来继续学习博弈论的知识.今天我们会学习更多的基础模型,以及SJ定理的应用. 首先,我们来看博弈论在DAG上的应用.首先来看一个小例子:在一个有向无环图中,有一个棋子从某一个点开始一直向它的出 ...

  7. [您有新的未分配科技点]博弈论入门:被博弈论支配的恐惧(Nim游戏,SG函数)

    今天初步学习了一下博弈论……感觉真的是好精妙啊……希望这篇博客可以帮助到和我一样刚学习博弈论的同学们. 博弈论,又被称为对策论,被用于考虑游戏中个体的预测行为和实际行为,并研究他们的应用策略.(其实这 ...

  8. 三十分钟理解博弈论“纳什均衡” -- Nash Equilibrium

    欢迎转载,转载请注明:本文出自Bin的专栏blog.csdn.net/xbinworld. 技术交流QQ群:433250724,欢迎对算法.技术感兴趣的同学加入. 纳什均衡(或者纳什平衡),Nash ...

  9. xtuoj 1235 CQRXLB(博弈论)

    CQRXLB Accepted : 19   Submit : 40 Time Limit : 1000 MS   Memory Limit : 65536 KB CQRXLB Problem Des ...

  10. HDU 5299 Circles Game 博弈论 暴力

    Circles Game 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5299 Description There are n circles on ...

随机推荐

  1. SpringCloud bootstrap.yml 和application.yml 加载原理

    Spring Cloud 官方文档:https://cloud.spring.io/spring-cloud-static/spring-cloud.html 一个Spring Cloud的操作是通过 ...

  2. 辗转相除 求最大公约数!or 最小公倍数

    求最大公约数和最小公倍数的经典算法--辗转相除法描述如下: 若要求a,b两数的最大公约数和最小公倍数,令a为a.b中较大数,b为较小数,算法进一步流程: while(b不为0) { temp=a%b: ...

  3. Python 3.10 is coming!

    看看Python 官网的文档 whatsnew,Python 3.10 已然距离我们越来越近了,然我们看看 Python 3.10 相较于 Python 3.9 有哪些改变吧 新特性 通过括号来组织多 ...

  4. 腾讯云 TKE Everywhere 特性发布,用户可在自有基础设施中托管 K8s 服务

    作者 孔令飞,腾讯云资深工程师,拥有大规模 Kubernetes 集群.微服务的研发和架构经验,目前专注于云原生混合云领域的基础架构开发. 朱翔,腾讯云容器服务高级产品经理,目前负责云原生混合云产品方 ...

  5. 用vue的抽象组件来做一个防止img标签url为空或url地址出错的验证

    看了网上文章学习了下vue的抽象组件,感觉就跟react的高阶组件一样的使用场景,只是更加面向vue的底层编程 ,网上介绍的抽象组件一般有2种用法,1 用来加防抖和节流 2 用来控制按钮是否允许点击做 ...

  6. MySQL基础——常用命令

    一.连接MySQL 1.启动mysql首先在打开cmd窗口,输入mysql -uroot -p ,然后空格进入MySQL控制台,MySQL的提示符是: mysql>. mysql -uroot ...

  7. Windows系统定时备份MySQL数据库

    当一个网站投入使用时,定期备份数据库是必要的事.那么,在Windows系统上,我们该如何做呢? 如下语句可以实现备份及还原MySQL数据库: 备份MySQL数据库 mysqldump -uroot - ...

  8. NOIP模拟16:「Star Way To Heaven·God Knows·Loost My Music」

    T1:Star Way To Heaven 基本思路:   最小生成树.   假如我们将上边界与下边界看作一个点,然后从上边界经过星星向下边界连边,会发现,他会形成一条线将整个矩形分为左右两个部分. ...

  9. Pytest 系列(29)- 详解 allure.dynamic 动态生成功能

    如果你还想从头学起Pytest,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1690628.html 前言 @allure.title  ...

  10. 给dubbo贡献源码,做梦都在修bug

    本文已收录 https://github.com/lkxiaolou/lkxiaolou 欢迎star. 一 在之前的文章<redis在微服务领域的贡献>中,从一次面试经历中了解了redi ...