zoukankan      html  css  js  c++  java
  • Codeforces 538E Demiurges Play Again(博弈DP)

    http://codeforces.com/problemset/problem/538/E

    题目大意:

    给出一棵树,叶子节点上都有一个值,从1-m。有两个人交替从根选择道路,先手希望到达的叶子节点尽量大,后手希望到达的叶子节点尽量小,叶子节点的放置方案任意。两个人都足够聪明,能够得到的最大值和最小值分别是多少。

    思路:

    先考虑最大的情况

    考虑dp[i]代表i这个节点能达到的最大的数字在这个子树中排第几。

    如果当前是先手操作,那么他肯定会往最大的那个子树的方向走,即dp[u]=min(dp[v])

    如果当前是后手操作,那么他肯定往最小的走,即dp[u]=Σdp[v],这样就走到了最差子树的最大数字去了。

    然后最小的情况类似

     

     1 #include<cstdio>
     2 #include<cmath>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<iostream>
     6 int tot,go[400005],next[400005],first[200005];
     7 int n,f1[400005],f2[400005],pd[400005],son[400005],deep[400005];
     8 int read(){
     9     int t=0,f=1;char ch=getchar();
    10     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    11     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
    12     return t*f;
    13 }
    14 void insert(int x,int y){
    15     tot++;
    16     go[tot]=y;
    17     next[tot]=first[x];
    18     first[x]=tot;
    19 }
    20 void add(int x,int y){
    21     insert(x,y);
    22     insert(y,x);
    23 }
    24 void dfs(int x,int fa){
    25     int pdd=0;
    26     for (int i=first[x];i;i=next[i]){
    27         int pur=go[i];
    28         if (pur==fa) continue;
    29         pdd=1;
    30         deep[pur]=deep[x]+1;
    31         dfs(pur,x);
    32         son[x]+=son[pur];
    33     }
    34     if (!pdd) son[x]=1,pd[x]=1;
    35 }
    36 void dfs1(int x,int fa){
    37     if (pd[x]==1) {
    38         f1[x]=1;
    39         return;
    40     }
    41     if (deep[x]%2){
    42      f1[x]=0x7fffffff;
    43      for (int i=first[x];i;i=next[i]){
    44          int pur=go[i];
    45          if (pur==fa) continue;
    46          dfs1(pur,x);
    47          f1[x]=std::min(f1[x],f1[pur]);
    48      }
    49     }else{
    50      f1[x]=0;
    51      for (int i=first[x];i;i=next[i]){
    52          int pur=go[i];
    53          if (pur==fa) continue;
    54          dfs1(pur,x);
    55          f1[x]+=f1[pur];
    56      }
    57     }
    58 }
    59 void dfs2(int x,int fa){
    60     if (pd[x]==1) {
    61         f2[x]=1;
    62         return;
    63     }
    64     if (deep[x]%2){
    65      f2[x]=0;
    66      for (int i=first[x];i;i=next[i]){
    67          int pur=go[i];
    68          if (pur==fa) continue;
    69          dfs2(pur,x);
    70          f2[x]+=f2[pur];
    71      }
    72     }else{
    73      f2[x]=0x7fffffff;
    74      for (int i=first[x];i;i=next[i]){
    75          int pur=go[i];
    76          if (pur==fa) continue;
    77          dfs2(pur,x);
    78          f2[x]=std::min(f2[x],f2[pur]);
    79      }
    80     }
    81 }
    82 int main(){
    83     n=read();
    84     for (int i=1;i<n;i++){
    85         int x=read(),y=read();
    86         add(x,y);
    87     }
    88     deep[1]=1;
    89     dfs(1,0);
    90     dfs1(1,0);
    91     printf("%d ",son[1]-f1[1]+1);
    92     dfs2(1,0);
    93     printf("%d
    ",f2[1]);
    94     return 0;
    95 }

     

     

     

  • 相关阅读:
    第四周PLECS仿真
    三相异步电动机预习笔记
    第三周PLECS仿真
    《自动化技术中的进给电气传动》 1.3节及《控制系统设计指南》 第一,二章设计指南读书笔记
    第二周 PLECS仿真
    机电传动课程学习
    《实时控制软件设计》2017年度教学总结
    《实时控制软件设计》2017年教学内容
    《机电传动控制》(2017)综合作业
    《机电传动控制》(2017)第十一周作业
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5627678.html
Copyright © 2011-2022 走看看