原题传送门
这题挺简单
首先可以知道一个强连通分量要么全部选,要么全不选
所以缩点
缩好以后建新图,注意连边方向,从
d
[
i
]
d[i]
d[i]连到
i
i
i
满足拓扑
在DAG上跑DP
d
p
[
u
]
[
m
]
表
示
点
u
时
,
重
量
最
多
为
m
的
最
大
价
值
dp[u][m]表示点u时,重量最多为m的最大价值
dp[u][m]表示点u时,重量最多为m的最大价值
转移显然
Code:
#include <bits/stdc++.h>
#define maxn 510
using namespace std;
struct Edge{
int to, next;
}edge[maxn * maxn];
int num, head[maxn], Index, dfn[maxn], low[maxn], vis[maxn], top, sta[maxn], tot;
int color[maxn], w[maxn], v[maxn], W[maxn], V[maxn], d[maxn], deg[maxn], n, m;
int dp[maxn][maxn];
inline int read(){
int s = 0, w = 1;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') w = -1;
for (; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) + (c ^ 48);
return s * w;
}
void addedge(int x, int y){ edge[++num] = (Edge) { y, head[x] }; head[x] = num; }
void tarjan(int u){
dfn[u] = low[u] = ++Index;
vis[u] = 1, sta[++top] = u;
for (int i = head[u]; i; i = edge[i].next){
int v = edge[i].to;
if (!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]); else
if (vis[v]) low[u] = min(low[u], dfn[v]);
}
if (dfn[u] == low[u]){
++tot;
while (sta[top + 1] != u)
color[sta[top]] = tot, vis[sta[top]] = 0, W[tot] += w[sta[top]], V[tot] += v[sta[top--]];
}
}
void dfs(int u){
for (int i = W[u]; i <= m; ++i) dp[u][i] = V[u];
for (int i = head[u]; i; i = edge[i].next){
int v = edge[i].to;
dfs(v);
for (int j = m; j >= W[u]; --j)
for (int k = 0; k <= j - W[u]; ++k)
dp[u][j] = max(dp[u][j], dp[v][k] + dp[u][j - k]);
}
}
int main(){
n = read(), m = read();
for (int i = 1; i <= n; ++i) w[i] = read();
for (int i = 1; i <= n; ++i) v[i] = read();
for (int i = 1; i <= n; ++i) d[i] = read(), addedge(d[i], i);
for (int i = 1; i <= n; ++i)
if (!dfn[i]) tarjan(i);
num = 0;
memset(head, 0, sizeof(head));
for (int i = 1; i <= n; ++i)
if (color[d[i]] != color[i] && d[i]) addedge(color[d[i]], color[i]), ++deg[color[i]];
for (int i = 1; i <= tot; ++i)
if (!deg[i]) addedge(tot + 1, i);
dfs(tot + 1);
printf("%d\n", dp[tot + 1][m]);
return 0;
}

本文介绍了一种结合强连通分量与动态规划(DP)解决特定图论问题的方法。通过缩点和拓扑排序,在有向无环图(DAG)上进行DP求解最大价值问题。代码实现包括了强连通分量的Tarjan算法及DP转移过程。
349

被折叠的 条评论
为什么被折叠?



