【jzoj5053】【石子游戏】【搜索】

16 篇文章 0 订阅

题目大意

桌面上有n堆石子,第i堆中有a[i]个石子,你和你的好朋友玩NIM游戏。你很绅士的让你的好朋友先手,但是,为了展示自己的聪明才智,你想确保自己能够胜利。于是,趁你好朋友不在的时候,你悄悄地从口袋里摸出一些石子,并决定在桌面上若干石子堆中放入一些新石子,并从若干个石子堆中拿走一些石子(可以取完石子堆,但是不能创造新的石子堆)你希望在新的游戏局面中确保自己必胜,同时,为了避免被发现,你对现有局面不能改动过大,因此,我们定义,对取走和放入的每个石子,你需要支付一点代价。你想知道,要得到一个自己必胜的游戏局面,最少需要支付多少代价。

解题思路

我们的目标是使异或和为零,从高到低位枚举,要变的情况我们有两种决策,把最小的1压倒刚刚好为0,把最大的0升到刚好为1,优先选当前代价最少的,最优性剪枝即可。

code

#include<set>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LD double
#define LL long long
#define ULL unsigned long long
#define min(a,b) ((a<b)?a:b)
#define max(a,b) ((a>b)?a:b)
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
#define fr(i,j) for(int i=begin[j];i;i=next[i])
using namespace std;
int const mn=1e5+9,mp=8*1e6+9,con=1e5+1,inf=1e9;
int n,gra,begin[mn],to[mn],next[mn],a[mn],b[mn],c[mn],dep[mn],
    du[mn],fail[mn],q[mn],fa[mn],pon=1;LL ans;
void insert(int u,int v){
    to[++gra]=v;
    next[gra]=begin[u];
    begin[u]=gra;
}
void dfs(int now){
    fr(i,now){
        dep[to[i]]=dep[now]+1;
        dfs(to[i]);
    }
}
int main(){
    freopen("route.in","r",stdin);
    freopen("route.out","w",stdout);
    scanf("%d",&n);int u,v;
    fo(i,1,n-1){
        scanf("%d%d",&u,&v);
        insert(v,u);
        fa[u]=v;du[u]++;du[v]++;
    }
    dep[1]=1;dfs(1);
    LL ans=0;
    fo(i,1,n){
        ans+=dep[i];
        if(dep[i]>dep[a[du[i]]])a[du[i]]=i;
    }
    fo(i,1,n){
        int now=a[i];
        if(now){
            fo(j,1,n)if(j!=now){
                int u=now,v=j;
                while(u&&v&&(du[u]==du[v]))
                ans--,u=fa[u],v=fa[v];
            }
        }
    }
    printf("%lld\n",ans);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值