[BZOJ4033] [HAOI2015] 樹上染色
阿新 • • 發佈:2019-03-31
std www void dig putc main ace 題目 clu
題目鏈接
BZOJ.
洛谷.
Solution
考慮\(dp\),設\(f[x][i]\)表示\(x\)的子樹選\(i\)個黑點對答案造成的貢獻的最大值。
註意這裏是對答案的貢獻,對於每條邊,如果一側的黑點個數是\(x\),白點是\(y\),那麽貢獻就是\(w\cdot (x\cdot (k-x)+y\cdot (n-k-y)))\)。
那麽轉移就很顯然了,直接背包一下就好了。
#pragma GCC optimize(3) #include<bits/stdc++.h> using namespace std; void read(int &x) { x=0;int f=1;char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f; for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f; } #define ll long long void print(ll x) { if(x<0) putchar('-'),x=-x; if(!x) return ;print(x/10),putchar(x%10+48); } void write(ll x) {if(!x) putchar('0');else print(x);putchar('\n');} #define lf double const int maxn = 2e3+10; const int inf = 1e9; const lf eps = 1e-8; ll f[maxn][maxn]; int n,k,head[maxn],tot,sz[maxn]; struct edge{int to,nxt,w;}e[maxn<<1]; void add(int u,int v,int w) {e[++tot]=(edge){v,head[u],w},head[u]=tot;} void ins(int u,int v,int w) {add(u,v,w),add(v,u,w);} void dfs(int x,int fa) { f[x][0]=f[x][1]=0,sz[x]=1; for(int i=head[x];i;i=e[i].nxt) if(e[i].to!=fa) dfs(e[i].to,x),sz[x]+=sz[e[i].to]; for(int v,i=head[x];i;i=e[i].nxt) { if((v=e[i].to)==fa) continue; for(int s=min(sz[x],k);~s;s--) for(int j=0;j<=min(s,sz[v]);j++) if(~f[x][s-j]) f[x][s]=max(f[x][s],f[x][s-j]+f[v][j]+1ll*e[i].w*(j*(k-j)+(sz[v]-j)*(n-k-sz[v]+j))); } } int main() { read(n),read(k); for(int i=1,x,y,z;i<n;i++) read(x),read(y),read(z),ins(x,y,z); memset(f,-1,sizeof f);dfs(1,0); write(f[1][k]); return 0; }
[BZOJ4033] [HAOI2015] 樹上染色