E. Nastya and Potions

发布时间 2023-10-06 15:02:36作者: 不o凡

E. Nastya and Potions

思路:直接对比制造这份药剂和直接买那个更好

判断特殊:
1.如果已经拥有就不用再买了
2.如果只能买,就直接买
方法:
1.dfs,因为要制造3,可能先要制造1,这样我们就dfs把条件从叶子节点全都往上传就行
优化:
1.如果之前已经知道了制造的价格,那么直接返回就行
注意点:
1.可能有些药剂不用钱,因此初始化为-1

点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
#define LL long long
LL c[N],a[N], cnt[N],f[N];
vector<int> g[N];
int dfs(int x) {
	if (f[x] != -1) return f[x];//之前已经知道了,直接返回
	LL w = 0;
	for (auto v : g[x]) {
		if (v == 0) {
			f[x] = c[x];//标记
			return f[x];//必须买,直接返回
		}
		w+=dfs(v);
	}
	f[x] =min(w,c[x]);//取最小
	return f[x];
}
void solve() {
	int n, k;
	cin >> n >> k;
	for (int i = 1; i <= n; i++) g[i].clear();
	memset(f, -1, sizeof f);
	memset(cnt, 0, sizeof cnt);
	for (int i = 1; i <= n; i++) cin >> c[i];
	for (int i = 1; i <= k; i++) {
		int x;
		cin >> x;
		f[x]=0;//不用钱,直接返回
	}
	for (int i = 1; i <= n; i++) {
		int m;
		cin >> m;
		for (int j = 1; j <= m; j++) {
			int x;
			cin >> x;
			g[i].push_back(x);//记录每个药水的制造步骤
		}
		if (m == 0) g[i].push_back(0);
	}
	for (int i = 1; i <= n; i++) {
		dfs(i);
	}
	for (int i = 1; i <= n; i++) cout << f[i] << ' ';
	cout << '\n';
}
int main() {
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int t;
	cin >> t;
	while (t--) {
		solve();
	}
	return 0;
}