• HDU6662 Acesrc and Travel


    题意

    给一棵树,每个点有权值a和b,两人博弈,先手选一个点开始走,两人轮流走相邻且没走过的点直至无法再走。每到一个点,先手得a分,后手得b分。求两人都使用最优策略的情况下,两人分数差。
    题目链接

    思路

    树形dp,求出每个点先手选择它,走到它子树的叶子节点的最大次大值,用f[x][0]表示,以及每个点后手选择它,走到它子树的叶子节点的最小次小值,用f[x][1]表示。再dfs一遍,过程中维护向它父亲走,它的父亲是先后手的值。特殊考虑的情况是如果是叶子节点只能向父亲走,根节点是叶子节点额外维护。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const LL INF = 1e16;
    const int maxn = 100000+10;
    
    int n;
    int a[maxn],b[maxn],c[maxn];
    int pre[2*maxn],other[2*maxn],last[maxn],du[maxn];
    LL f1[maxn][2],f2[maxn][2];
    int tot;
    LL ans;
    bool jud;
    
    void add(int x,int y)
    {
        tot++;
        pre[tot]=last[x];
        last[x]=tot;
        other[tot]=y;
        du[y]++;
    }
    
    void dfs1(int x,int fa)
    {
        LL mn1=INF,mx1=-INF;
        LL mn2=INF,mx2=-INF;
        int num=0;
        for (int p=last[x];p;p=pre[p])
        {
            int q=other[p];
            if (q==fa) continue;
            num++;
            dfs1(q,x);
            if (f1[q][1]<=mn1)
            {
                mn2=mn1;
                mn1=f1[q][1];
            } else
            if (f1[q][1]<mn2)
            {
                mn2=f1[q][1];
            }
            if (f1[q][0]>=mx1)
            {
                mx2=mx1;
                mx1=f1[q][0];
            } else
            if (f1[q][0]>mx2)
            {
                mx2=f1[q][0];
            }
        }
        if (num==0) mn1=mx1=0;
        f1[x][0]=c[x]+mn1;
        f2[x][0]=c[x]+mn2;
        f1[x][1]=c[x]+mx1;
        f2[x][1]=c[x]+mx2;
        if (x==1&&num==1) jud=1;
    }
    
    void dfs2(int x,int fa,LL pre0,LL pre1)
    {
        if (x==1) ans=max(ans,f1[x][0]); else
        if (du[x]==1) ans=max(ans,pre1+c[x]); else ans=max(ans,min(f1[x][0],pre1+c[x]));
        for (int p=last[x];p;p=pre[p])
        {
            int q=other[p];
            if (q==fa) continue;
            LL p0,p1;
            if (x==1)
            {
                if (jud)
                {
                    p0=p1=c[x];
                } else
                {
                    if (f1[x][0]==f1[q][1]+c[x]) p0=f2[x][0]; else p0=f1[x][0];
                    if (f1[x][1]==f1[q][0]+c[x]) p1=f2[x][1]; else p1=f1[x][1];
                }
            } else
            {
                if (f1[x][0]==f1[q][1]+c[x]) p0=min(f2[x][0],pre1+c[x]); else p0=min(f1[x][0],pre1+c[x]);
                if (f1[x][1]==f1[q][0]+c[x]) p1=max(f2[x][1],pre0+c[x]); else p1=max(f1[x][1],pre0+c[x]);
            }
            dfs2(q,x,p0,p1);
        }
    }
    
    int main()
    {
        int T;
        scanf("%d",&T);
        while (T--)
        {
            scanf("%d",&n);
            tot=0;
            for (int i=1;i<=n;i++) last[i]=0,du[i]=0;
            for (int i=1;i<=n;i++) scanf("%d",&a[i]);
            for (int i=1;i<=n;i++) scanf("%d",&b[i]);
            for (int i=1;i<=n;i++) c[i]=a[i]-b[i];
            for (int i=1;i<n;i++)
            {
                int x,y;
                scanf("%d%d",&x,&y);
                add(x,y);
                add(y,x);
            }
            jud=0;
            dfs1(1,0);
            ans=-INF;
            dfs2(1,0,0,0);
            printf("%lld
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    【GPS】Android O平台如何设置SUPL地址,以及GPS三个配置文件的优先级分析
    【GPS】gps.conf文件解读
    【GPS】SAP测试GPS模块拿不到sensor数据
    Linux系统安装Samba共享服务器详解及安装配置
    CentOS 6.5 编译安装 LNMP环境
    linux禁止root用户直接登录
    Linux下安装配置日志服务器
    Windows系统安装Oracle 11g客户端
    Linux系统zabbix_agentd客户端安装与配置
    Redhat6.5——解决yum功能不能正常使用
  • 原文地址:https://www.cnblogs.com/zhanggengchen/p/11425381.html
Copyright © 2020-2023  润新知