动态规划(树形DP):HDU 5886 Tower Defence
Sample Input
2 3 2 1 2 3 2 5 5 2 1 7 3 1 7 4 2 5 5 2 6
Sample Output
7 63
这类题目就是分类讨论,需要多做做。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 const int N=100010; 6 int cnt,fir[N],nxt[N*2],to[N*2],val[N*2]; 7 void addedge(int a,int b,int v){ 8 nxt[++cnt]=fir[a]; 9 to[fir[a]=cnt]=b; 10 val[cnt]=v; 11 } 12 int Mx[N],dp[N][3],pos[N][2]; 13 void Update(int x,int d,int t){ 14 if(d>dp[x][0]){dp[x][2]=dp[x][1];dp[x][1]=dp[x][0];pos[x][1]=pos[x][0];pos[x][0]=t;dp[x][0]=d;} 15 else if(d>dp[x][1]){dp[x][2]=dp[x][1];pos[x][1]=t;dp[x][1]=d;} 16 else if(d>dp[x][2])dp[x][2]=d; 17 } 18 void DFS(int x,int fa){ 19 for(int i=fir[x];i;i=nxt[i]) 20 if(to[i]!=fa){DFS(to[i],x); 21 int d=dp[to[i]][0]+val[i]; 22 Mx[x]=max(Mx[x],Mx[to[i]]); 23 Update(x,d,to[i]); 24 } 25 Mx[x]=max(Mx[x],dp[x][0]+dp[x][1]); 26 } 27 28 int down[N],give[N]; 29 long long ans; 30 void DP(int x,int fa){ 31 Update(x,give[x],0);//往回走的最长链 32 int d1=0,d2=0,p,d; 33 for(int i=fir[x];i;i=nxt[i]) 34 if(to[i]!=fa){ 35 if(Mx[to[i]]>d1)d2=d1,d1=Mx[to[i]],p=to[i]; 36 else if(Mx[to[i]]>d2)d2=Mx[to[i]]; 37 } 38 for(int i=fir[x];i;i=nxt[i]) 39 if(to[i]!=fa){ 40 if(pos[x][0]==to[i])d=dp[x][1]+dp[x][2]; 41 else if(pos[x][1]==to[i])d=dp[x][0]+dp[x][2]; 42 else d=dp[x][0]+dp[x][1]; 43 44 if(to[i]!=p)d=max(d,d1); 45 else d=max(d,d2); 46 47 d=max(down[x],d);ans+=max(Mx[to[i]],d);down[to[i]]=d; 48 if(pos[x][0]!=to[i])give[to[i]]=dp[x][0]+val[i]; 49 else give[to[i]]=dp[x][1]+val[i]; 50 DP(to[i],x); 51 } 52 } 53 54 void Init(){ 55 memset(give,0,sizeof(give)); 56 memset(down,0,sizeof(down)); 57 memset(fir,0,sizeof(fir)); 58 memset(pos,0,sizeof(pos)); 59 memset(Mx,0,sizeof(Mx)); 60 memset(dp,0,sizeof(dp)); 61 ans=cnt=0; 62 } 63 int T,n; 64 int main(){ 65 scanf("%d",&T); 66 while(T--){ 67 Init();scanf("%d",&n); 68 for(int i=1,a,b,v;i<n;i++){ 69 scanf("%d%d%d",&a,&b,&v); 70 addedge(a,b,v);addedge(b,a,v); 71 } 72 DFS(1,1);DP(1,1); 73 printf("%lld\n",ans); 74 } 75 return 0; 76 }
尽最大的努力,做最好的自己!