cdoj 1136 邱老師玩遊戲 樹形揹包

轉自:http://www.cnblogs.com/qscqesze/p/4971434.html
邱老師玩遊戲

Time Limit: 20 Sec

Memory Limit: 256 MB
題目連接

http://acm.uestc.edu.cn/#/problem/show/1136
Description

邱老師最近在玩一種戰略遊戲,在一個地圖上,有N座城堡,每座城堡都有一定的寶物,在每次遊戲中邱老師允許攻克M個城堡並獲得裏面的寶物。

但由於地理位置原因,有些城堡不能直接攻克,要攻克這些城堡必須先攻克其他某一個特定的城堡。你能幫邱老師算出要獲得儘量多的寶物應該攻克哪M個城堡嗎?

Input

每個測試實例首先包括2個整數,N,M.(1 <= M <= N <= 200);

在接下來的N行裏,每行包括2個整數,a,b.

在第 i 行,a 代表要攻克第 i 個城堡必須先攻克第 a 個城堡,如果 a = 0 則代表可以直接攻克第 i 個城堡。b 代表第 i 個城堡的寶物數量, b >= 0。

當N = 0, M = 0輸入結束。

Output

對於每個測試實例,輸出一個整數,代表邱老師攻克M個城堡所獲得的最多寶物的數量。

Sample Input

3 2
0 1
0 2
0 3
7 4
2 2
0 1
0 4
2 1
7 1
7 6
2 2
0 0

Sample Output

5
13

分析:其實就是冬季賽的樹的揹包的題目。

vector<int> Q[205];
long long dp[205][205];
int vis[205];
int b[205];
int n,m;
void dfs(int x)
{
    if(vis[x])return;
    vis[x]=1;
    dp[x][1]=b[x];
    for(int i=0;i<Q[x].size();i++)
    {
        int v = Q[x][i];
        dfs(v);
        for(int j=m;j>=0;j--)
            for(int k=0;k<j;k++)
                dp[x][j]=max(dp[x][j],dp[v][k]+dp[x][j-k]);
    }
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        if(n==0&&m==0)break;m++;
        for(int i=0;i<=n;i++)
            Q[i].clear();
        memset(vis,0,sizeof(vis));
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++)
        {
            int x;scanf("%d%d",&x,&b[i]);
            Q[x].push_back(i);
        }
        dfs(0);
        printf("%lld\n",dp[0][m]);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章