2286: [Sdoi2011 Consumption war time limit:20 Sec Memory limit:512 MB
submit:1815 solved:645
[Submit] [Status] [Discuss] Description In a war, the battlefield consists of N islands and n-1 bridges, guaranteeing that there is only one path to each of the two islands. Now, our army has detected the enemy's headquarters in the numbered 1 islands, and they have not enough energy to sustain the battle, our victory is in sight. Known to have abundant energy on other K islands, our mission is to blow up some bridges to prevent enemy forces from reaching any energy-rich islands. Due to the different materials and structures of different bridges, the cost of blowing up different bridges is different, and our army wants to meet the target and make the total cost minimum. The investigation department also found that the enemy had a mysterious machine. Even after our troops cut off all the energy, they could use that machine. The effect of the machine is not only to repair all the bridges that our army has blown up, but also to re-distribute the resources randomly (but it is guaranteed that the resources will not be distributed on Island 1th). But the investigation department also found that the machine can only use M-times, so we just need to complete each task. Input
The first line is an integer n, representing the number of islands.
Next n-1 line, each line of three integer u,v,w, represents the U island and the V Island by a cost of C bridge directly connected to ensure 1<=u,v<=n and 1<=c<=100000.
Line n+1, an integer m, representing the number of times an enemy machine can be used.
Next M line, an integer ki per line, representing the first time after, there are Ki Islands rich, followed by K-integers h1,h2,... HK, representing the number of resource-rich islands.
Output
The output has m lines, representing the minimum cost per task, respectively.
Sample Input10
1 5 13
1 9 6
2 1 19
2 4 8
2 3 91
5 6 8
7 5 4
7 8 31
10 7 9
3
2 10 6
4 5 7) 8 3
3 9 4 6Sample Output12
32
22HINT
For 100% of data, 2<=n<=250000,m>=1,sigma (KI) <=500000,1<=ki<=n-1
For each query, a tree DP is used once to produce the result.
DP equation:
F[father]+=fmin (G[son]?inf:f[son], (Min_e (son,father));(G[i] Mark is a key point)
This time efficiency is very intuitive O (m*n)
For each query, we only need to traverse the LCA between the key points and the key points, while the other points are negligible or can be skipped.
Then we need to use the technique of virtual tree, the virtual tree is to maintain a monotonous stack of the key points of the tree and the LCA between them in accordance with the DFS sequence traversal, the process of traversing through the adjustment of the monotonous stack to clarify the relationship between the father and son of the tree.
First, Dfs is performed on the tree node. The node is labeled DFN during the period.
Then, maintain a monotonic stack. The nodes of this monotonous stack are all on a chain.
For the top element of the stack p, the stack of the top element Q, will be inserted node X has the following relationship:
1.lca is P. At this time DFN (x) >DFN (P) =DFN (LCA)
This means that x is below the p and the x is placed directly into the stack.
2.P and X are separated under two subtrees trees of LCA. DFN (x) >DFN (p) >dfn (ILCA) at this time
There are three kinds of discussions.
The edge of this problem is the tree-type DP processing
(1) if DFN (q) >DFN (LCA), you can directly connect the edge q->p, and then back up the stack.
(2) if DFN (q) =DFN (LCA), indicating Q=lca, directly connected to the edge of Lca->p, put p back to the stack, when the subtree has been built.
(3) if DFN (q) <DFN (LCA), the LCA is the P and Q sandwiched between the middle, at this time the Edge lca->q, put p back stack, and then put the LCA into the stack. The subtree is now built.
Repeat to judge the above process
This handles the Min_e (P,Q) p to Q in the path of the least weighted edge. It is also possible to multiply the LCA or the tree profile. See the Challenge Program Design Contest, change the code.
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <vector> #include < Algorithm> #define Find_min (A, b) a>b?b:a#define max_v 250008#define max_log_v 21#define inf 0x3f3f3f3f#define inf ( 1ll<<40) using namespace std;typedef long Long int ll; struct edge{int to,cost;}; Vector<edge> g[max_v];int par[max_log_v][max_v];//v node go up 2^k step to the node int mng[max_log_v][max_v];//v node up 2^ K Step passing the smallest side int dfn[max_v];//DFS ordinal designator for each point int dep[max_v];//depth ll f[max_v];//tree dp struct node{int H,DFN;} Hs[max_v];bool g[max_v];//is the key point int sta[max_v*2];//analog stack int icnt;//stack top, id int swap (int &x,int &y) {//Interchange x=x^y;y=x^ Y,x=x^y;} Current point, Father node, depth, Benquan void dfs (int v,int p,int d,int pre_e) connection father Point {//lca search preprocessing par[0][v]=p,dep[v]=d,mng[0][v]=pre_e,dfn[v]= icnt++;for (int i=0;i<g[v].size (); ++i) if (g[v][i].to!=p) DFS (g[v][i].to,v,d+1,g[v][i].cost);} void Init_tree () {///Pre-processing LCA query icnt=0;//id initialized to 0 dfs (1,-1,0,inf); for (int. k=0;k+1<max_log_v;++k) for (int V=1;v<=max _V;++V) {if (par[k][V]<0)//over root par[k+1][v]=-1,mng[k+1][v]=inf;else{//can advance 2^ (k+1) step int u=par[k][v]; par[k+1][v]=par[k][u]; Mng[k+1] [V]=find_min (Mng[k][v],mng[k][u]);}} int LCA (int u,int v) {if (Dep[u]>dep[v]) swap (U,V);//first to the same depth for (int k=0;k<max_log_v;++k) if ((Dep[v]-dep[u]) > >k & 1) v=par[k][v];if (U==V) return u;//simultaneous up binary query for (int k=max_log_v-1;k>=0;--k) if (Par[k][u]!=par[k][v]) u= Par[k][u],v=par[k][v];return par[0][u];} int min_e (int u,int v) {int Ilca=lca (u,v); int Res=inf;//u->lca int mov;if (Dep[ilca]<dep[u]) {MOV=DEP[U]-DEP[ILCA] ; for (int k=0;k<max_log_v;++k) if (mov>>k &1) res=find_min (Res,mng[k][u]), U=par[k][u];} V->lca if (Dep[ilca]<dep[v]) {mov=dep[v]-dep[ilca];for (int k=0;k<max_log_v;++k) if (mov>>k &1) Res=find_min (Res,mng[k][v]), v=par[k][v];} return res;} void Add_edge (int u,int v,int c) {G[u].push_back (edge) {v,c}); G[v].push_back (Edge) {u,c});} void init () {//Initialize the number of edges 0 for (int i=0;i<max_v;++i) g[i].clear ();} int cmp (const void *a,const void *b) {return ((node *) a)->dfn-((node *) b)->dfn;} ll Fmin (ll A,ll b) {return a>b?b:a;} void solve (int k) {for (int i=1;i<=k;++i) {int o=hs[i].h;hs[i].dfn=dfn[o];//synchronous search Id}qsort (hs+1,k,sizeof (hs[0]), CMP ); int tp=0;sta[tp]=0;sta[++tp]=1;f[1]=0,g[1]=0;for (int i=1;i<=k;++i) {int P=sta[tp],q=sta[tp-1],x=hs[i].h;int Ilca=lca (P,x), while (Dfn[p]>dfn[ilca]) {if (Dfn[q]<=dfn[ilca]) {int tmp=fmin (G[TP]?INF:F[TP], (LL) min_e (P,ilca ); Sta[tp--]=0;if (ilca!=q) sta[++tp]=ilca,f[tp]=0,g[tp]=0;f[tp]+=tmp;break;} Else{f[tp-1]+=fmin (G[TP]?INF:F[TP], (LL) min_e (p,q)); sta[tp--]=0;} P=STA[TP],Q=STA[TP-1];} if (sta[tp]!=x) sta[++tp]=x,f[tp]=0;g[tp]=1;} while (tp>1) {int p=sta[tp],q=sta[tp-1];f[tp-1]+=fmin (G[TP]?INF:F[TP], (LL) min_e (p,q)); sta[tp--]=0;} printf ("%lld\n", f[tp--]);} int main () {int n;while (~scanf ("%d", &n)) {init (); int u,v,w;for (int i=0;i<n-1;++i) {scanf ("%d%d%d",&u,& V,&W); Add_edge (u,v,w);} Init_tree (); int m,k,h;scanf ("%d", &m), while (m--) {scanf ("%d", &k), and for (int i=1;i<=k;++i) scanf ("%d",& Hs[i].h); solve (k);}} return 0;}
bzoj-2286 consumption War "virtual tree + multiplication lca+ monotonic stack"