jzoj3347,bzoj3257-[NOI2013模拟]树的难题【树形dp】
生活随笔
收集整理的這篇文章主要介紹了
jzoj3347,bzoj3257-[NOI2013模拟]树的难题【树形dp】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
正題
BZOJBZOJBZOJ題目鏈接:https://www.lydsy.com/JudgeOnline/problem.php?id=3257
題目大意
一棵樹上的節點有333種顏色,有邊權。
選擇一些邊割掉使得森林中每棵樹只有一個白點或沒有黑點。
求割掉的邊的最小值。
解題思路
定義fi,statef_{i,state}fi,state?表示iii的子樹中割掉后森林所有的樹都滿足條件且目前子樹連接的點狀態為statestatestate。
下面給出狀態
| 000 | 000 | 000 |
| 111 | 0~∞0\sim \infty0~∞ | 000 |
| 222 | 000 | 0~∞0\sim \infty0~∞ |
| 333 | 0or10\ or\ 10?or?1 | 000 |
| 444 | 0or10\ or\ 10?or?1 | 0~∞0\sim \infty0~∞ |
然后如果對于狀態s1s1s1和s2s2s2。若s1s1s1可以轉移到s2s2s2
fx,s1=fx,s1+fy,s2f_{x,s1}=f_{x,s1}+f_{y,s2}fx,s1?=fx,s1?+fy,s2?
否則
fx,s1=fx,s1+fy,s2+wx,yf_{x,s1}=f_{x,s1}+f_{y,s2}+w_{x,y}fx,s1?=fx,s1?+fy,s2?+wx,y?
然后要注意后兩個狀態的白色只能傳一個白色上來所有需要特殊處理
需要注意的是在野雞jzojjzojjzoj中會爆棧,這里是先進行一次拓撲排序再dpdpdp
codecodecode
#include<cstdio> #include<cstring> #include<algorithm> #define xf(z) f[x][z] #define yf(z) f[y][z] #define min3(a1,a2,a3) min(min(a1,a2),a3) #define min4(a1,a2,a3,a4) min(min(a1,a2),min(a3,a4)) #define min5(a1,a2,a3,a4,a5) min(min(min(a1,a2),min(a3,a4)),a5) #define ll long long using namespace std; const ll N=301000,inf=1e18; struct Edge_node{ll to,next,w; }a[N*2]; ll T,n,c[N],ls[N],tot,f[N][5],q[N],fa[N]; void addl(ll x,ll y,ll w) {a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;a[tot].w=w; } void dfs() {int head=1,tail=0;q[++tail]=1;while(head<=tail){int x=q[head++];for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(y==fa[x]) continue;fa[y]=x;q[++tail]=y;}}for(int i=tail;i>=1;i--){int x=q[i];ll white1=0,white2=0;for(ll i=ls[x];i;i=a[i].next){ll y=a[i].to,z;if(y==fa[x]) continue;xf(0)+=min(min4(yf(1),yf(2),yf(3),yf(4))+a[i].w,yf(0));xf(1)+=min(min3(yf(0),yf(1),yf(2)),min(yf(3),yf(4))+a[i].w);xf(2)+=(z=min(yf(0),min4(yf(1),yf(2),yf(3),yf(4))+a[i].w));white1=max(white1,z-yf(2));xf(3)+=(z=min(min(yf(0),yf(4)),min3(yf(3),yf(2),yf(1))+a[i].w));white2=max(white2,z-min(yf(3),yf(2)));xf(4)+=min(min(yf(0),yf(4)),min3(yf(1),yf(2),yf(3))+a[i].w);}xf(2)-=white1;xf(3)-=white2;if(c[x]==1){xf(3)=xf(4);xf(2)=xf(0);xf(1)=min3(xf(0),xf(1),xf(2));xf(0)=xf(4)=inf;}else if(c[x]==0){xf(3)=min3(xf(3),xf(2),xf(0));xf(0)=xf(1)=xf(2)=inf;}xf(1)=min3(xf(1),xf(0),xf(2));xf(2)=min(xf(2),xf(0));xf(3)=min3(xf(3),xf(2),xf(0));xf(4)=min(xf(4),xf(0));} } int main() {scanf("%lld",&T);while(T--){memset(f,0,sizeof(f));memset(ls,0,sizeof(ls));tot=0;scanf("%lld",&n);for(ll i=1;i<=n;i++)scanf("%lld",&c[i]);for(ll i=1;i<n;i++){ll x,y,w;scanf("%lld%lld%lld",&x,&y,&w);addl(x,y,w);addl(y,x,w);}dfs();printf("%lld\n",min5(f[1][0],f[1][1],f[1][2],f[1][3],f[1][4]));} } 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的jzoj3347,bzoj3257-[NOI2013模拟]树的难题【树形dp】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 米兔5X手表重置恢复出厂设置的方法米兔手
- 下一篇: jzoj3348,bzoj3258-秘密