【HDOJ6662】Acesrc and Travel(树形DP,换根)

题意:有一棵n个点的树,每个点上有两个值a[i],b[i]

A和B在树上行动,A到达i能得到a[i]的偷税值,B能得到b[i],每次行动只能选择相邻的点作为目标

两个人都想最大化自己的偷税值和对方的差,都按最优策略行动,不能走已经走过的点,行动直到没有点可走为止

A可以选择任意出发点,然后B开始走,然后A开始走……

n<=1e5,0<=a[i],b[i]<=1e9

思路:

f[u][0]表示从u出发下一步走儿子的min,f[u][1]表示max

g[u][0]表示从u出发下一步走父亲的min,g[u][1]表示max

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 typedef unsigned int uint;
  5 typedef unsigned long long ull;
  6 typedef pair<int,int> PII;
  7 typedef pair<ll,ll> Pll;
  8 typedef vector<int> VI;
  9 typedef vector<PII> VII;
 10 //typedef pair<ll,ll>P;
 11 #define N  1000010
 12 #define M  200010
 13 #define fi first
 14 #define se second
 15 #define MP make_pair
 16 #define pb push_back
 17 #define pi acos(-1)
 18 #define mem(a,b) memset(a,b,sizeof(a))
 19 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
 20 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
 21 #define lowbit(x) x&(-x)
 22 #define Rand (rand()*(1<<16)+rand())
 23 #define id(x) ((x)<=B?(x):m-n/(x)+1)
 24 #define ls p<<1
 25 #define rs p<<1|1
 26 
 27 const int MOD=1e9+7,inv2=(MOD+1)/2;
 28       double eps=1e-4;
 29       int INF=1e9;
 30       int inf=0x7fffffff;
 31       int dx[4]={-1,1,0,0};
 32       int dy[4]={0,0,-1,1};
 33 
 34 ll f[N][2],g[N][2];
 35 ll t1[N],t2[N],t3[N],t4[N],t5[N],t6[N],a[N],b[N];
 36 int head[N],vet[N],nxt[N],d[N],tot;
 37 
 38 
 39 int read()
 40 {
 41    int v=0,f=1;
 42    char c=getchar();
 43    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
 44    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
 45    return v*f;
 46 }
 47 
 48 void add(int a,int b)
 49 {
 50     nxt[++tot]=head[a];
 51     vet[tot]=b;
 52     head[a]=tot;
 53 }
 54 
 55 void dfs1(int u,int fa)
 56 {
 57     int e=head[u],s=0;
 58     ll t1=INF,t2=-INF;
 59     while(e)
 60     {
 61         int v=vet[e];
 62         if(v!=fa)
 63         {
 64             s++;
 65             dfs1(v,u);
 66             t1=min(t1,f[v][1]);
 67             t2=max(t2,f[v][0]);
 68         }
 69         e=nxt[e];
 70     }
 71     if(s)
 72     {
 73         f[u][0]=t1+a[u]-b[u];
 74         f[u][1]=t2+a[u]-b[u];
 75     }
 76      else f[u][0]=f[u][1]=a[u]-b[u];
 77 }
 78 
 79 void dfs2(int u,int fa)
 80 {
 81     int s=0;
 82     int e=head[u];
 83     while(e)
 84     {
 85         int v=vet[e];
 86         if(v!=fa)
 87         {
 88             s++;
 89             t1[s]=f[v][0];
 90             t2[s]=f[v][1];
 91         }
 92         e=nxt[e];
 93     }
 94     t3[1]=t1[1];
 95     rep(i,2,s) t3[i]=max(t3[i-1],t1[i]);
 96     t4[s]=t1[s];
 97     per(i,s-1,1) t4[i]=max(t4[i+1],t1[i]);
 98     t5[1]=t2[1];
 99     rep(i,2,s) t5[i]=min(t5[i-1],t2[i]);
100     t6[s]=t2[s];
101     per(i,s-1,1) t6[i]=min(t6[i+1],t2[i]);
102     e=head[u];
103     int i=0;
104     while(e)
105     {
106         int v=vet[e];
107         if(v!=fa)
108         {
109             i++;
110             ll t=g[u][1];
111             ll t0=-INF;
112             if(i-1>=1) t0=max(t0,t3[i-1]+a[u]-b[u]);
113             if(i+1<=s) t0=max(t0,t4[i+1]+a[u]-b[u]);
114             if(u==1&&s>1) t=t0;
115              else t=max(t,t0);
116             g[v][0]=a[v]-b[v]+t;
117             t=g[u][0];
118             t0=INF;
119             if(i-1>=1) t0=min(t0,t5[i-1]+a[u]-b[u]);
120             if(i+1<=s) t0=min(t0,t6[i+1]+a[u]-b[u]);
121             if(u==1&&s>1) t=t0;
122              else t=min(t,t0);
123             g[v][1]=a[v]-b[v]+t;
124         }
125         e=nxt[e];
126     }
127     e=head[u];
128     while(e)
129     {
130         int v=vet[e];
131         if(v!=fa) dfs2(v,u);
132         e=nxt[e];
133     }
134 }
135 
136 
137 int main()
138 {
139     //freopen("1.in","r",stdin);
140     int cas;
141     scanf("%d",&cas);
142     while(cas--)
143     {
144         int n=read();
145         rep(i,1,n) a[i]=read();
146         rep(i,1,n) b[i]=read();
147         rep(i,1,n) head[i]=d[i]=0;
148         tot=0;
149         rep(i,1,n-1)
150         {
151             int x=read(),y=read();
152             add(x,y);
153             add(y,x);
154             d[x]++; d[y]++;
155         }
156         dfs1(1,0);
157         g[1][0]=g[1][1]=a[1]-b[1];
158         dfs2(1,0);
159         ll ans=-INF;
160         rep(i,1,n)
161         {
162             if(i==1) ans=max(ans,f[i][0]);
163              else if(d[i]==1) ans=max(ans,g[i][0]);
164               else ans=max(ans,min(f[i][0],g[i][0]));
165         }
166         printf("%I64d
",ans);
167 
168     }
169 
170     return 0;
171 }
原文地址:https://www.cnblogs.com/myx12345/p/11655728.html