求大佬 hack
查看原帖
求大佬 hack
448887
cancan123456楼主2022/9/22 21:47
#include <cstdio>
using namespace std;
const int N = 105;
const int M = 505;
struct Graph {
	bool edge[N][N];
	int w[N], v[N];
	void add_edge(int u, int v) {
		edge[u][v] = true;
	}
} input, g;
int n, m, dfn[N], dfncnt, low[N], stack[N], top, belong[N], scccnt;
bool in_stack[N];
int min(int a, int b) {
	return a < b ? a : b;
}
void dfs(int u) {
	dfncnt++;
	low[u] = dfn[u] = dfncnt;
	top++;
	stack[top] = u;
	in_stack[u] = true;
	for (int v = 1; v <= n; v++) {
		if (input.edge[u][v]) {
			if (dfn[v] == 0) {
				dfs(v);
				low[u] = min(low[u], low[v]);
			} else if (in_stack[v]) {
				low[u] = min(low[u], dfn[v]);
			}
		}
	}
	if (dfn[u] == low[u]) {
		scccnt++;
		int x;
		do {
			x = stack[top];
			top--;
			belong[x] = scccnt;
		} while (x != u);
	}
}
struct Result {
	int f[M];
	Result() {
		for (int i = 0; i < M; i++) {
			f[i] = 0;
		}
	}
	Result(int w, int v) {
		for (int i = 0; i < M; i++) {
			f[i] = 0;
		}
		f[w] = v;
	}
};
int max(int a, int b) {
	return a > b ? a : b;
}
Result operator + (const Result & a, const Result & b) {
	Result c;
	for (int i = 0; i <= m; i++) {
		for (int j = 0; i + j <= m; j++) {
			c.f[i + j] = max(c.f[i + j], a.f[i] + b.f[j]);
		}
	}
	return c;
}
Result f[N];
void dp(int u, int fa) {
	f[u] = Result(g.w[u], g.v[u]);
	for (int v = 1; v <= scccnt; v++) {
		if (g.edge[u][v] && v != fa) {
			dp(v, u);
			f[u] = f[u] + f[v];
		}
	}
}
int main() {
	scanf("%d %d", &n, &m);
	for (int i = 1; i <= n; i++) {
		scanf("%d", &input.w[i]);
	}
	for (int i = 1; i <= n; i++) {
		scanf("%d", &input.v[i]);
	}
	for (int d, i = 1; i <= n; i++) {
		scanf("%d", &d);
		input.add_edge(d, i);
	}
	for (int i = 1; i <= n; i++) {
		if (dfn[i] == 0) {
			dfs(i);
		}
	}
	for (int u = 1; u <= n; u++) {
		for (int v = 1; v <= n; v++) {
			if (belong[u] != belong[v] && input.edge[u][v]) {
				g.add_edge(belong[u], belong[v]);
			}
		}
	}
	for (int u = 1; u <= n; u++) {
		g.w[belong[u]] += input.w[u];
		g.v[belong[u]] += input.v[u];
	}
	Result ans;
	for (int u = 1; u <= scccnt; u++) {
		bool root = true;
		for (int v = 1; v <= scccnt; v++) {
			if (g.edge[v][u]) {
				root = false;
				break;
			}
		}
		if (root) {
			dp(u, 0);
			ans = ans + f[u];
		}
	}
	int res = 0;
	for (int i = 0; i <= m; i++) {
		res = max(res, ans.f[i]);
	}
	printf("%d", res);
	return 0;
}

0pts

2022/9/22 21:47
加载中...