bzoj 2427

来源:互联网 发布:清除网页上的淘宝广告 编辑:程序博客网 时间:2024/06/18 21:15

有依赖的背包
tarjan 缩点 + treedp

就写n * C 的有依赖的背包 什么辣鸡 n*C^2 我不学

/**************************************************************    Problem: 2427    User: fengchanghn    Language: C++    Result: Accepted    Time:4 ms    Memory:1556 kb****************************************************************/ #include <bits/stdc++.h>using namespace std;typedef long long LL;const int INF = 0x3f3f3f3f;inline int read(void){    int x = 0, c = 0, f = 1;    for(;c<'0'||c>'9';c=getchar())f=c!='-';    for(;c>='0'&&c<='9';c=getchar())x=x*10+c-'0';    return f ? x : -x;}const int N = 120, M = 550;int v[N], w[N], V[N], W[N],Index;int dfn[N],low[N],col_cnt,col[N],sta[N], stop;int f[N][M], n, m, fir[N], from[N], to[N], nxt[N],edge_cnt;vector<int> G[N];inline void addedge(int u,int v){    from[++edge_cnt] = u;    to[edge_cnt] = v;    nxt[edge_cnt] = fir[u];    fir[u] = edge_cnt;}bool vis[N];void dfs(int x) {    low[x] = dfn[x] = ++Index;    sta[++stop] = x, vis[x] = 1;    for (int i = fir[x]; i; i = nxt[i]) {        if (!dfn[to[i]]) {            dfs(to[i]);            low[x] = min(low[x], low[to[i]]);        }         else if (vis[to[i]]) low[x] = min(low[x], dfn[to[i]]);    }    if (dfn[x] != low[x]) return;    int y; col_cnt++;    do {        y = sta[stop], stop--;        V[col_cnt] += v[y];        W[col_cnt] += w[y];        vis[y] = 0, col[y] = col_cnt;    } while (y != x);}void treedp(int x,int C) {    if (C < 0) return;    for (vector<int>::iterator i=G[x].begin(); i != G[x].end(); i++) {        for (int j = 0; j <= C; j++) f[*i][j] = f[x][j];        treedp(*i, C - W[*i]);        for (int j = W[*i]; j <= C; j++)            f[x][j] = max(f[x][j], f[*i][j-W[*i]]+V[*i]);    }}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,x; i <= n; i++) {        x = read();        addedge(x, i);    }    for (int i = 1; i <= n; i++)        if (!dfn[i]) dfs(i);    for (int i = 1; i <= edge_cnt; i++) {        if (col[from[i]] != col[to[i]]) {            G[col[from[i]]].push_back(col[to[i]]);            vis[col[to[i]]] = 1;        }    }    for (int i = 1; i <= col_cnt; i++)        if (!vis[i]) G[0].push_back(i);    treedp(0, m);    cout << f[0][m] << endl;}
原创粉丝点击