Test instructions
Given a non-root tree with n nodes, there are two devices A and B, each of which has an infinite number. The use of a device at a node x requires the cost of C1, and the edges that are connected to node X are overwritten at this time. The use of a B device at a node x requires the cost of C2, and at this point the edges connected to node X and the points connected to the X are overwritten. Minimum cost to cover all edges.
Analysis:
First, the root tree can be identified by DFS first. Consider the effect of selecting device A and Unit B.
Device A only affects the edges that the node U is connected to. The device B also affects the side of the point connected to u, that is, the edge that is 2 from the node U is also affected.
That is, for the Edge (U,fa[u]), if FA[FA[U]] is loaded with device B, then this edge is overwritten. But is this the only case? One easy leak is if you and V's father are fa[u], and if device B is installed at V, then the side (U,fa[u]) is covered. (People like me who think things are not comprehensive, it is easy to miss this situation, resulting in my later the entire code re-hit again ~ ~)
And for device A, the process is relatively simple, the following I just say how I deal with device B.
Using a four-dimensional dp,dp[x][a][b][c] (a=0~2; b=0~2; c=0~1) means node x, a device is selected (0 means no, 1 means device a,2 for device B), fa[x] selected B device, the current side (U,fa[u]) state is c.
If c=0, then you must have at least one of the child nodes installed on the device B. And for the second case of the above mentioned device B, we can also use this to calculate together.
Then there are two scenarios:
1. At least one of the child nodes of U is loaded with device B.
2, the child node of U is not loaded with device B.
When the condition is met, take the min value of both.
The code is as follows:
1#include <cstdio>2#include <cstdlib>3#include <cstring>4#include <iostream>5#include <algorithm>6 using namespacestd;7 #defineMAXN 100108 #defineINF 1000000109 Ten intdp[maxn][3][3][2]; One intFIRST[MAXN],FA[MAXN]; A intn,c1,c2; - - structnode the { - intX,y,next; -}t[2*MAXN];intLen; - + voidInsintXinty) - { +t[++len].x=x;t[len].y=y; At[len].next=first[x];first[x]=Len; at } - - intMymin (intXintY) {returnX<y?x:y;} - - voidDfsintXintf) - { infa[x]=F; - for(intI=first[x];i;i=t[i].next)if(t[i].y!=f) to { + inty=t[i].y; - DFS (y,x); the } * } $ Panax Notoginseng intFfind (intXintAintBintC//a->x B->fa c-> (x,fa[x]) - { the if(Dp[x][a][b][c]<inf)returnDp[x][a][b][c]; + intans=Dp[x][a][b][c]; A intP= (a!=0|| b==2)?1:0, h=0, Y,now; the for(intI=first[x];i;i=t[i].next)if(T[i].y!=fa[x])//sons has at least one B + { -y=t[i].y; $Now=mymin (Mymin (Ffind (Y,0A1), Ffind (Y,1A1)), Ffind (Y,2A1)); $h+=Now ; - } - for(intI=first[x];i;i=t[i].next)if(t[i].y!=Fa[x]) the { -y=t[i].y;WuyiNow=mymin (Mymin (Ffind (Y,0A1), Ffind (Y,1A1)), Ffind (Y,2A1)); theAns=mymin (Ans,h-now+ffind (Y,2A1)); - } Wu if(c!=0)//Sons has no B - { Aboutnow=0; $ for(intI=first[x];i;i=t[i].next)if(t[i].y!=Fa[x]) - { -y=t[i].y; -Now+=mymin (Ffind (Y,0, a,p), Ffind (Y,1A1)); A } +ans=mymin (ans,now); the } - if(a==1) ans+=C1; $ Else if(a==2) ans+=C2; thedp[x][a][b][c]=ans; the returnans; the } the - intMain () in { the while(1) the { Aboutscanf"%d%d%d",&n,&c1,&C2); the if(n==0&&c1==0&&c2==0) Break; thelen=0; thememset (First,0,sizeof(first)); + for(intI=1; i<n;i++) - { the intx, y;Bayiscanf"%d%d",&x,&y); the ins (x, y); ins (y,x); the } -Memset (DP, the,sizeof(DP)); -Dfs1,0); the intans=INF; theAns=mymin (Ans,ffind (1,0,0,1)); theAns=mymin (Ans,ffind (1,1,0,1)); theAns=mymin (Ans,ffind (1,2,0,1)); -printf"%d\n", ans); the } the return 0; the}
UVA12093
2016-03-10 17:16:10
"uva12093" Protecting Zonk (tree-shaped DP)