8.10-Day2T3 镇守府

emm

IOI原题(洛谷,bzoj都有)

其实并没有怎么搞懂dp方程转移那部分

就...粘个(抄来的)代码过来吧

#include<bits/stdc++.h>
using namespace std;

inline int read()
{
    int sum = 0,p = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
        if(ch == '-')
            p = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        (sum *= 10) += ch - '0';
        ch = getchar();
    }
    return sum * p;
}

const int N = 205,M = 55;
const int inf = 0x3f3f3f3f;
int n,m,head[N],w[N],f[N],cnt;
int dis[N][N],dp[N][M][N];
struct edge
{
    int nxt,to;
}e[N];

void add(int a,int b)
{
    e[++cnt].nxt = head[a];
    e[cnt].to = b;
    head[a] = cnt;
}

void dfs(int u)
{
    for(int last = u,i = f[u]; i != -1; i = f[i])
    {
        dis[u][i] = dis[u][last] + dis[last][i];
        last = i;
    }
    for(int i = head[u]; i; i = e[i].nxt)
        dfs(e[i].to);
}

void tree_dp(int u)
{
    bool flag = true;
    for(int i = head[u]; i; i = e[i].nxt)
    {
        flag = false;
        tree_dp(e[i].to);
    }
    if(flag)
    {
        for(int i = f[u]; i != -1; i = f[i])
            dp[u][0][i] = dis[u][i] * w[u];
        return;
    }
    if(u != 0)
        dp[u][0][u] = inf;
    for(int i = head[u]; i; i = e[i].nxt)
    {
        int v = e[i].to;
        for(int p = f[u]; p != -1; p = f[p])
        {
            for(int j = m; j >= 0; j--)
            {
                int tmp = inf;
                for(int k = 0; k <= j; k++)
                    tmp = min(tmp,dp[u][k][p] + dp[v][j - k][p]);
                dp[u][j][p] = tmp;
            }
        }
        for(int j = m; j >= 0; j--)
        {
            int tmp = inf;
            for(int k = (u != 0); k <= j; k++)
                tmp = min(tmp,dp[u][k][u] + dp[v][j - k][u]);
            dp[u][j][u] = tmp;
        }
    }
    for(int p = f[u]; p != -1; p = f[p])
        for(int i = 0; i <= m; i++)
        {
            dp[u][i][p] += dis[u][p]*w[u];
            dp[u][i][p] = min(dp[u][i][p],dp[u][i][u]);
        }
}

int main()
{
    freopen("riv.in","r",stdin);
    freopen("riv.out","w",stdout);
    n = read(),m = read();
    for(int i = 1; i <= n; i++)
    {
        w[i] = read();
        f[i] = read();
        dis[i][f[i]] = read();
        add(f[i],i);
    }
    f[0] = -1;
    dfs(0);
    tree_dp(0);
    printf("%d\n",dp[0][m][0]);
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/darlingroot/p/11345263.html
今日推荐