POJ 2152 Fire(树形DP)

题目链接:http://poj.org/problem?id=2152

题意:

POJ 2152 Fire(树形DP)_第1张图片

思路:令F[i][j]表示

POJ 2152 Fire(树形DP)_第2张图片

的最小费用。Best[i]表示以i为根节点的子树多有节点都找到负责消防站的最小费用。

POJ 2152 Fire(树形DP)_第3张图片

POJ 2152 Fire(树形DP)_第4张图片

int n,w[N],d[N];
vector<pair<int,int> > g[N];
int f[N][N],dis[N],best[N];

void dfs(int u)
{
    int i,v;
    FOR0(i,SZ(g[u]))
    {
        v=g[u][i].first;
        if(dis[v]!=-1) continue;
        dis[v]=dis[u]+g[u][i].second;
        dfs(v);
    }
}

void DFS(int u,int pre)
{
    int i,j,v;
    FOR0(i,SZ(g[u]))
    {
        v=g[u][i].first;
        if(v!=pre) DFS(v,u);
    }
    clr(dis,-1); dis[u]=0; dfs(u);
    FOR1(i,n) f[u][i]=INF;
    best[u]=INF;
    FOR1(i,n) if(dis[i]<=d[u])
    {
        f[u][i]=w[i];
        FOR0(j,SZ(g[u]))
        {
            v=g[u][j].first;
            if(v==pre) continue;
            f[u][i]+=min(best[v],f[v][i]-w[i]);
        }
        best[u]=min(best[u],f[u][i]);
    }
}

int main()
{
    rush()
    {
        RD(n);
        int i;
        FOR1(i,n) RD(w[i]);
        FOR1(i,n) RD(d[i]);
        FOR1(i,n) g[i].clear();
        FOR1(i,n-1)
        {
            int u,v,w;
            RD(u,v,w);
            g[u].pb(MP(v,w));
            g[v].pb(MP(u,w));
        }
        DFS(1,0);
        PR(best[1]);
    }
}

  

 

你可能感兴趣的:(poj)