[CF Round603 Div2 F]Economic Difficulties

Topic: Economic Difficulties

Portal: https://codeforces.com/contest/1263/problem/F

Question is intended: to the two tree: Ta (has a node, the node number [n + 1, n + a]) Tb (has b nodes, node number: [n + a + 1, n + a + b ]) where two tree leaf node is connected successively according to the sequence dfs $ i, i \ in [1, n] $ node can ask the maximum number of nodes on the tree removed, such that each $ i, i \ in [ 1, n] $ can still communicate Ta, Tb, or the root node.

analysis:

1. a practice: https://codeforces.com/blog/entry/71844?locale=en

Similar generalization backpack, each article or a selected, or select B, successively selected additional contribution, assuming cost_a [i, j] Representative [i, J] to select a range contribution, cost_b [i, j] Representative [i , j] to select the interval b contribution.

DP [i] Representative prior node i, the equation: $$ dp [i] = max \ {dp [j] + cost [j + 1, i] \} $$

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 vector< vector<int> > calc_cost(int vn, int n, vector<int> fa, vector<int> tg) {
 5     vector< vector<int> > res(n+1, vector<int>(n+1));
 6     for (int l = 1; l <= n; l++) {
 7         vector<int> deg(vn+1);
 8         for (int i = 2; i <= vn ; i++) deg[fa[i]]++;
 9         int val = 0;
10         for (int r = l; r <= n; r++) {
11             for(int v = tg[r]; v != 1 && deg[v] == 0; --deg[v = fa[v]]) 
12                 val++;
13             res[l][r] = val;
14         }
15     }
16     return res;
17 }
18 
19 int main() {
20     int n;
21     scanf("%d", &n);
22     vector< vector<int> > cost[2];
23     for (int j = 0; j < 2; j++) {
24         int vn;
25         scanf("%d", &vn);
26         vector<int> fa(vn+1);
27         vector<int> tg(n+1);
28         for (int i = 2; i <= vn; i++) scanf("%d", &fa[i]);
29         for (int i = 1; i <= n;  i++)  scanf("%d", &tg[i]);
30         cost[j] = calc_cost(vn, n, fa, tg);
31     }
32     
33     vector<int> dp(n + 1, 0);
34     for (int i = 1; i <= n; i++) 
35         for (int j = 0; j < i; j++) 
36             dp[i] = max(dp[i], dp[j] + max(cost[0][j+1][i], cost[1][j+1][i]));
37     printf("%d", dp[n]);
38     return 0;
39 }
View Code

2. Based on the final results, we certainly choose some nodes Ta and Tb, the removal of these nodes and their descendant nodes, taking into account here, as long as we control the range of each node calculated, and then follow the left endpoint or endpoints have sorted and then do the restrictions backpack dp.

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e4 + 7;
const int INF = 1e9 + 7;
vector< pair<pair<int,int>, int> > vec;
int sz[MAXN], st[MAXN], ed[MAXN], tg[MAXN];
vector<int> G[MAXN];
void dfs(int u) {
    sz[u] = 1;
    st[u] = INF; ed[u] = -INF;
    if(tg[u]) st[u] = ed[u] = tg[u];
    for(auto v : G[u]) {
        dfs(v);
        sz[u] += sz[v];
        st[u] = min(st[u], st[v]);
        ed[u] = max(ed[u], ed[v]);
    }
    vec.push_back(make_pair(make_pair(ed[u], st[u] - 1), sz[u]-(u == 1)));
}
int dp[MAXN];
int main() {
    int n, a, x;
    scanf("%d", &n);
    for(int j = 0; j < 2; j++) { 
        scanf("%d", &a);
        for(int i = 2;i <= a; i++) {
            scanf("%d", &x);
            G[x].push_back(i);
        }
        for(int i = 1; i <= n; i++) {
            scanf("%d", &x);
            tg[x] = i;
        }
        dfs(1);
        for(int i = 1; i <= a; i++) {
            G[i].clear();
            tg[i] = 0;
        }
    }
    sort(vec.begin(), vec.end());
    for(auto it : vec) {
        int l = it.first.second, r = it.first.first;
        dp[r] = max(dp[r], dp[l] + it.second);
    }
    printf("%d", dp[n]);
    return 0;
}

 

3. Division of Arts and similar, the problem can be solved with a network flow, but I still do not know why he was right.

 

#include <bits/stdc++.h>
using namespace std;
typedef int LL;
const int MAXN = 1e5 + 7;
const int MAXM = 1e5 + 7;
const int INF = 1e9 + 7;

namespace NWF {
    struct Edge {
        int to, nxt;LL f;
    } e[MAXM << 1]; 
    int S, T, tot;
    int ecnt, head[MAXN], cur[MAXN], dis[MAXN];
    queue<int> q;
    void init(int _S, int _T, int _tot){
        ecnt = 1; S = _S; T = _T; tot = _tot;
        memset(head, 0, (tot + 1) * sizeof(int));
    } 
    void addEdge(int u, int v, LL f) {
        e[++ecnt] = (Edge) {v, head[u], f}; head[u] = ecnt;
        e[++ecnt] = (Edge) {u, head[v], 0}; head[v] = ecnt;
    }
    bool bfs() {
        memset(dis, 0, (tot + 1) * sizeof(int));
        q.push(S); dis[S] = 1;
        while (!q.empty()) {
            int u = q.front(), v; q.pop();
            for (int i = cur[u] = head[u]; i ; i = e[i].nxt) {
                if (e[i].f && !dis[v = e[i].to]) {
                    q.push(v);
                    dis[v] = dis[u] + 1;
                }
            }
        }
        return dis[T];
    }
    LL dfs(int u, LL maxf) {
        if (u == T) return maxf;
        LL sumf = maxf;
        for (int &i = cur[u]; i; i = e[i].nxt) {
            if (e[i].f && dis[e[i].to] > dis[u]) {
                LL tmpf = dfs(e[i].to, min(sumf, e[i].f));
                e[i].f -= tmpf; e[i ^ 1].f += tmpf;
                sumf -= tmpf;
                if (!sumf) return maxf;
            }
        }
        return maxf - sumf;
    }
    LL dinic() {
        LL ret = 0;
        while (bfs()) ret += dfs(S, INF);
        return ret;
    }
}
int faa[MAXN], fab[MAXN], tga[MAXN], tgb[MAXN];
int main() {
    int n, A, B;
    scanf("%d", &n);
    scanf("%d", &A);
    for(int i = 2;i <= A; i++) scanf("%d", faa+i);
    for(int i = 1; i <= n; i++) scanf("%d", tga + i);
    scanf("%d", &B);
    for(int i = 2;i <= B; i++) scanf("%d", fab+i);
    for(int i = 1; i <= n; i++) scanf("%d", tgb + i);
        
    NWF::init(A+B+1,A+B+2, A+B+3);
    for ( Corinthians = 2 ; <= A; ++ ) { 
        NWF :: addEdge (NWF :: S, I, 1 ); 
        NWF :: addEdge (faa [you], you, inf); 
    } 
    For ( Corinthians = 2 ; <= B; ++ ) { 
        NWF :: addEdge (A +, A + fab [you], inf); 
        NWF :: addEdge (A + i, NWF :: T, 1 ); 
    } 
    For ( Corinthians = 1 ; <= n; ++ ) 
        NWF :: addEdge (tga [you], A + tgb [you], inf); 
        
    Corinthians ans = A -1 + B - 1 - NWF::dinic();
    printf("%d", ans);
    return 0;
}
View Code

 

#include <bits/stdc++.h>
using namespace std;
typedef int LL;
const int MAXN = 1e5 + 7;
const int MAXM = 1e5 + 7;
const int INF = 1e9 + 7;

namespace NWF {
    struct Edge{
        int to, nxt;LL f;
    }e[MAXM << 1];
    int S, T, tot;
    int ecnt, head[MAXN], cur[MAXN], pre[MAXN], num[MAXN], dis[MAXN];
    queue<int> q;
    void init(int _S, int _T, int _tot){
        ecnt = 1; S = _S; T = _T; tot = _tot;
        memset(num,  0, (tot + 1) * sizeof(int));
        memset(head, 0, (tot + 1) * sizeof(int));
    } 
    inline void addEdge(int u, int v, LL f) {
        e[++ecnt] = (Edge) {v, head[u], f}; head[u] = ecnt;
        e[++ecnt] = (Edge) {u, head[v], 0}; head[v] = ecnt;
    }
    void bfs() {
        memset(dis, 0, (tot + 1) * sizeof(int));
        q.push(T);
        dis[T] = 1;
        while(!q.empty()) {
            int u = q.front(), v; q.pop();
            num[dis[u]]++;
            for(int i = cur[u] = head[u]; i; i = e[i].nxt) {
                if(!dis[v = e[i].to]) {
                    dis[v] = dis[u] + 1;
                    q.push(v);
                }
            }
        }
    }
    LL augment() {
        LL flow = INF;
        for(int i = S; i != T; i = e[cur[i]].to) 
            flow = min(flow, e[cur[i]].f);
        for(int i = S; i != T; i = e[cur[i]].to) {
            e[cur[i]].f -= flow;
            e[cur[i] ^ 1].f += flow;
        }
        return flow;
    }
    LL isap() {
        bfs();
        int u = S, v;
        LL flow = 0;
        while(dis[S] <= tot) {
            if(u == T) {
                flow += augment();
                u = S;
            }
            bool fg = 0;
            for(int i = cur[u]; i; i = e[i].nxt) {
                if(e[i].f && dis[u] > dis[v = e[i].to]) {
                    pre[v] = u;
                    cur[u] = i;
                    u = v;
                    fg = 1;
                    break;
                }
            }
            if(fg) continue;
            if(!--num[dis[u]]) break;
            int maxDis = tot;
            for(int i = head[u]; i; i = e[i].nxt) {
                if(e[i].f && maxDis > dis[v = e[i].to]) {
                    maxDis = dis[v];
                    cur[u] = i;
                }
            }
            num[dis[u] = maxDis + 1]++;
            if(u != S) u = pre[u];
        }
        return flow;
    }
}
int faa[MAXN], fab[MAXN], tga[MAXN], tgb[MAXN];
int main() {
    int n, A, B;
    scanf("%d", &n);
    scanf("%d", &A);
    for(int i = 2;i <= A; i++) scanf("%d", faa+i);
    for(int i = 1; i <= n; i++) scanf("%d", tga + i);
    scanf("%d", &B);
    for(int i = 2;i <= B; i++) scanf("%d", fab+i);
    for(int i = 1; i <= n; i++) scanf("%d", tgb + i);
        
    NWF::init(A+B+1, A + B + 2 , A + B + 3 );
    for ( Corinthians = 2 ; <= A; ++ ) { 
        NWF :: addEdge (NWF :: S, I, 1 ); 
        NWF :: addEdge (faa [you], you, inf); 
    } 
    For ( Corinthians = 2 ; <= B; ++ ) { 
        NWF :: addEdge (A +, A + fab [you], inf); 
        NWF :: addEdge (A + i, NWF :: T, 1 ); 
    } 
    For ( Corinthians = 1 ; <= n; ++ ) 
        NWF :: addEdge (tga [you], A + tgb[i], INF);
        
    int ans = A - 1 + B - 1 - NWF::isap();
    printf("%d", ans);
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/hjj1871984569/p/11973734.html