HDOJ6662Acesrc and Travel(树形DP,换根)
Posted myx12345
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDOJ6662Acesrc 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 }
以上是关于HDOJ6662Acesrc and Travel(树形DP,换根)的主要内容,如果未能解决你的问题,请参考以下文章
AtCoderC - Friends and Travel costs 模拟