cf Codeforces Round 888 E. Nastya and Potions

原题:
E. Nastya and Potions
time limit per test3 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Alchemist Nastya loves mixing potions. There are a total of n types of potions, and one potion of type i can be bought for ci coins.

Any kind of potions can be obtained in no more than one way, by mixing from several others. The potions used in the mixing process will be consumed. Moreover, no potion can be obtained from itself through one or more mixing processes.

As an experienced alchemist, Nastya has an unlimited supply of k types of potions p1,p2,…,pk, but she doesn’t know which one she wants to obtain next. To decide, she asks you to find, for each 1≤i≤n, the minimum number of coins she needs to spend to obtain a potion of type i next.

Input
The first line of each test contains an integer t (1≤t≤10^4) — the number of test cases.

Each test case is described as follows:

The first line contains two integers n and k (1≤k<n≤2⋅10^5) — the total number of potion types and the number of potion types Nastya already has.

The second line contains n integers c1,c2,…,cn (1≤ci≤10^9) — the costs of buying the potions.

The third line contains k distinct integers p1,p2,…,pk (1≤pi≤n) — the indices of potions Nastya already has an unlimited supply of.

This is followed by n lines describing ways to obtain potions by mixing.

Each line starts with the integer mi (0≤mi<n) — the number of potions required to mix a potion of the type i (1≤i≤n).

Then line contains mi distinct integers e 1 , e 2 , … , e m i e_1,e_2,…,e_{mi} e1,e2,,emi (1≤ej≤n, ej≠i) — the indices of potions needed to mix a potion of the type i. If this list is empty, then a potion of the type i can only be bought.

It is guaranteed that no potion can be obtained from itself through one or more mixing processes.

It is guaranteed that the sum of all n values across all test cases does not exceed 2⋅10^5
. Similarly, it is guaranteed that the sum of all mi values across all test cases does not exceed 2⋅10^5.

Output
For each test case, output n integers — the minimum number of coins Nastya needs to spend to obtain a potion of each type.

Examples
inputCopy
4
5 1
30 8 3 5 10
3
3 2 4 5
0
0
2 3 5
0
3 2
5 143 3
1 3
1 2
0
2 1 2
5 1
5 4 1 3 4
2
2 4 5
3 3 5 4
2 1 4
1 5
0
4 2
1 1 5 4
2 4
3 2 4 3
0
2 2 4
1 2
outputCopy
23 8 0 5 10
0 143 0
5 0 1 3 4
0 0 0 0
inputCopy
3
6 3
5 5 4 5 2 2
3 4 5
2 2 5
1 5
3 4 1 6
4 2 6 1 5
0
0
6 2
1 4 4 1 5 2
3 6
4 6 3 4 5
4 6 5 3 4
0
1 5
1 6
0
2 1
4 3
1
0
1 1
outputCopy
0 0 0 0 0 2
0 0 0 0 0 0
0 0
Note
In the first test case of the first sample, it is optimal:

Get a potion of the first type by buying and mixing 2, 4 and 5;
a potion of the second type can only be obtained by purchasing it;
Nastya already has an unlimited number of potions of the third type;
a potion of the fourth type is more profitable to buy than to buy and mix other potions;
a potion of the fifth type can only be obtained by purchasing it.

中文:
有n种药,每种药有可能使用其它几种已有的药进行合成且不会自己合成自己。给你c1到cn标识每种药的购买加个,其中有k种药p1到pk表示这k个药已经有了,而且无限供应。接下是n行,每行表示合成第i种药需要的其它药的下标。
最后输出n个整数,输出每种药获得的最少花销。

代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 2;
typedef long long ll;

int t, n, k, m;
ll c[maxn];
vector<int> E[maxn];
ll dp[maxn];

int dfs(ll cur) {
    if (dp[cur] != -1) {
        return dp[cur];
    }
    ll sum = 0;
    for (int i = 0; i < E[cur].size(); i++) {
        sum += dfs(E[cur][i]);
    }
    if (E[cur].empty()) {
        dp[cur] = c[cur];
    } else {
        dp[cur] = min(sum, c[cur]);
    }
    return dp[cur];
}

int main() {
    ios::sync_with_stdio(false);
    cin >> t;
    while (t--) {
        cin >> n >> k;
        memset(dp, -1, sizeof(dp));
        for (int i = 1; i <= n; i++) {
            E[i].clear();
        }
        int p;
        for (int i = 1; i <= n; i++) {
            cin >> c[i];
        }
        for (int i = 1; i <= k; i++) {
            cin >> p;
            c[p] = 0;
        }
        for (int i = 1; i <= n; i++) {
            cin >> m;
            for (int j = 0; j < m; j++) {
                int val;
                cin >> val;
                E[i].push_back(val);
            }
        }
        for (int i = 1; i <= n; i++) {
            if (dp[i] == -1) {
                dfs(i);
            }
        }
        for (int i = 1; i <= n; i++) {
            cout << dp[i];
            if (i!=n) {
                cout << " ";
            } else {
                cout << endl;
            }
        }
        cout << endl;
    }
    return 0;
}

解答:

好久好久没刷题了=_=|||
很简单很基础的记忆化搜索,每种药要么使用其它药合成,要么直接购买即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值