P2495 [SDOI2011] attrition (virtual tree + DP)

Title Description

In a war, the battlefield by n islands and bridges consisting of n-1, to ensure that there is only one path up between every two islands. Now, our military has to detect the enemy's headquarters at No. 1 for the island, and they do not have enough energy to maintain the fighting, military victory in sight. Known to have abundant energy on other islands k, in order to prevent the enemy access to energy, some of our military mission is to blow up the bridge, so that the enemy can not reach any energy-rich islands. Due to different materials and different structures of the bridge, the bridge to blow up different have different price, hope our military while meeting targets to minimize total costs.

Investigation department also found that there is a mysterious enemy machine. Even after the army cut off all energy, they can also use that machine. Machine-generated effects will not fix all of our military to blow up the bridge, and will re-random distribution of resources (but you can guarantee that resources are not distributed to No. 1 on the island). But the investigation also found that the department can only use this machine m times, so we just need to complete each task.

Input Format

A first line integer n, represents the number of islands.

Next, n-1 lines of three integers u, v, W, u represents number of islands and the islands bridge number v c is directly linked by a consideration, to ensure that a <= u, v <= n-1 and <= c <= 100000.

N + 1 th row, an integer m, the representative number of the enemy machine can be used.

Next m lines, each an integer ki, on behalf of the i-th, ki islands have rich resources, the next integer k h1, h2, ... hk, represents the number of resource-rich islands.

Output Format

It has m output lines, representing the minimum cost per task.

Sample input and output

Input # 1
10
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 6
Output # 1
12
32
22

Description / Tips

[Data] scale and conventions

Data for 10%, 2 <= n <= 10,1 <= m <= 5,1 <= ki <= n-1

Data for 20%, 2 <= n <= 100,1 <= m <= 100,1 <= ki <= min (10, n-1)

Data for 40%, 2 <= n <= 1000, m> = 1, sigma (ki) <= 500000,1 <= ki <= min (15, n-1)

To 100% of the data, 2 <= n <= 250000, m> = 1, sigma (ki) <= 500000,1 <= ki <= n-1

 

SOLUTION:

 

For each query keypoint, the establishment of the imaginary, the edge weights between two points is the lowest value in the original tree path between two points

dp time, when this point is the key point, the plus side right

If not, add min (right side, it takes all the key points in this subtree son off)

 

CODE:

 

#include"iostream"
#include"algorithm"
#include"vector"
#include"stdio.h"
using namespace std;
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)

const int N = 250007;


vector<int> RG[N],VG[N];
int U[N],V[N],C[N];
int dfn[N],deep[N];
ll me[N];
int fa[N][20];
int stk[N],top;
int idq[N],mark[N];
int n,m,idx;
int f[N][20];
int dp[N];
struct aa
{
    int so;
    int w;
};
vector<aa> G[N];

int LCA(int u,int v)
{
    if(deep[u] < deep[v]) swap(u,v);
    int delta = deep[u] - deep[v];
    for(int i = 19; i >= 0; --i)
    {
        if((delta >> i) & 1) u = fa[u][i];
    }
    for(int i = 19; i >= 0; --i)
    {
        if(fa[u][i] != fa[v][i]) u = fa[u][i],v = fa[v][i];
    }
    if(u == v) return u;
    return fa[u][0];
}

int DIS(int u,int v)
{
    if(deep[u] < deep[v]) swap(u,v);
    int delta = deep[u] - deep[v];
    int ans=1e16;
    for(int i = 19; i >= 0; --i)
    {
        if((delta >> i) & 1) ans=min(ans,f[u][i]),u = fa[u][i];
    }
    if(u == v) return ans;
    for(int i = 19; i >= 0; --i)
    {
        if(fa[u][i] != fa[v][i]) u = fa[u][i],v = fa[v][i];
    }

    return fa[u][0];
}

void insert2(int u)
{
    if(top == 1)
    {
        stk[++top] = u;
        return;
    }
    int lca = LCA(u,stk[top]);
    if(lca == stk[top])
    {
        stk[++top] = u;
        return ;
    }
    while(top > 1 && dfn[lca] <= dfn[stk[top-1]])
    {
        G[stk[top-1]].push_back({stk[top],DIS(stk[top],stk[top-1])});
        --top;
    }
    if(lca != stk[top])
    {
        G[lca].push_back({stk[top],DIS(stk[top],lca)});
        stk[top] = lca;
    }
    stk[++top] = u;
}

ll dp2(int x)
{
    ll cost=0;
    int len=G[x].size();
    for(int j=0;j<len;j++)
    {
        aa i=G[x][j];
        if(mark[i.so])cost+=i.w;
        else cost+=min(1ll*i.w,dp2(i.so));
    }
    return cost;

}
void Clear(int x)
{
    int len=G[x].size();
     for(int j=0;j<len;j++)
    {
        aa i=G[x][j];
        Clear(i.so);

    }
    G[x].clear();
}

/***********************************/


void dfs(int u)
{
    dfn[u] = ++idx;
    deep[u] = deep[fa[u][0]] + 1;
    int len=RG[u].size();
    for(int j=0;j<len;j++)
    {
        int e=RG[u][j];
        int v = U[e] ^ V[e] ^ u;
        if(v == fa[u][0]) continue;
        me[v] = C[e];
        f[v][0]=C[e];
        if(u != 1 && me[u] < me[v]) me[v] = me[u];
        fa[v][0] = u;
        dfs(v);
    }
}


bool comp(int a,int b)
{
    return dfn[a] < dfn[b];
}
/***********************************/

#define sc(x) scanf("%d",&(x))

signed main()
{
    cin >> n;
    for(int i = 1; i < n; ++i)
    {
        sc(U[i]); sc(V[i]); sc(C[i]);
        RG[U[i]].push_back(i);
        RG[V[i]].push_back(i);
    }
    dfs(1);

    for(int t = 1; t <= 19; ++t) for(int i = 1; i <= n; ++i)
        {
            fa[i][t] = fa[fa[i][t-1]][t-1];
            if(fa[i][t])  f[i][t] = min(f[i][t-1] , f[fa[i][t-1]][t-1]);
        }

    cin >> m;
    for(int i = 0; i < m; ++i)
    {
        int sz;
        sc(sz);
        for(int j = 0; j < sz; ++j)
        {
            sc(idq[j]);
            mark[idq[j]] = 1;
        }
        sort(idq,idq+sz,comp);
        top = 0;
        stk[++top] = 1;
        for(int j = 0; j < sz; ++j) insert2(idq[j]);
        while(top > 0)
        {
            G[stk[top-1] ].push_back({stk[top],DIS(stk[top-1],stk[top])});
            top--;
        }
        printf("%lld\n",dp2(1));
        Clear(1);
        for(int j = 0; j < sz; ++j) mark[idq[j]] = 0;

    }
    return 0;
}

  

 

 

 

 

 

Guess you like

Origin www.cnblogs.com/zhangbuang/p/11310467.html