1263F - Economic Difficulties - CodeForces Solution


data structures dfs and similar dp flows graphs trees *2400

Please click on ads to support us..

C++ Code:

#include <bits/stdc++.h>

#define ll long long
using namespace std;

const int N = 2005;
const int M = 15;

vector<int> adj[N][2];

int device[N][2];

int depth[N][2],anc[N][M][2];

//test

void dfs(int node,int par,int parity) {

    anc[node][0][parity] = par;
    for(int i=1;i<M;++i) {
        anc[node][i][parity] = anc[anc[node][i-1][parity]][i-1][parity];
    }

    for(int ch : adj[node][parity]) {
        if(ch!=par) {
            depth[ch][parity] = depth[node][parity] + 1;
            dfs(ch,node,parity);
        }
    }
}

pair<int,int> getAnc(int x,int y,int parity) {
    int ret = 0;
    if(depth[x][parity]<depth[y][parity]) {
        swap(x,y);
    }
    ret = depth[x][parity] - depth[y][parity];
    for(int i=0;i<M;++i) {
        if(ret&(1<<i)) {
            x = anc[x][i][parity];
        }
    }
    if(x!=y) {
        for(int i=M-1;i>=0;--i) {
            if(anc[x][i][parity]!=anc[y][i][parity]) {
                ret += 2*(1<<i);
                x = anc[x][i][parity];
                y = anc[y][i][parity];
            }
        }
        ret += 2;
        x = anc[x][0][parity];
        y = anc[y][0][parity];
    }
    assert(x==y);
    return {x,ret};
}

int preSet[N][N][2];
int dp[N][N][2][2];



int solveDp(int cur,int last,int up,int iter,int n) {
    if(cur>n) {
        return 0;
    }
    int &ret = dp[cur][last][up][iter];
    if(ret!=-1) {
        return ret;
    }
    ret = 1e9;

    if(iter) {
        ret = min(ret, solveDp(cur+1,last,up,iter,n) + preSet[cur-1][cur][up]);
        ret = min(ret, solveDp(cur+1,cur-1,up^1,1,n) + preSet[last][cur][up^1]);
    } else {
        assert(0);
    }
    return ret;
}

void solve2() {
    int n,a,b;
    scanf("%d ",&n);

    scanf("%d ",&a);
    for(int i=2;i<=a;++i) {
        int p;
        scanf("%d ",&p);
        adj[p][0].push_back(i);
    }
    for(int i=1;i<=n;++i) {
        scanf("%d ",&device[i][0]);
    }

    scanf("%d ",&b);

    for(int i=2;i<=b;++i) {
        int p;
        scanf("%d ",&p);
        adj[p][1].push_back(i);
    }
    for(int i=1;i<=n;++i) {
        scanf("%d ",&device[i][1]);
    }
    device[0][0] = device[0][1] = 1;
    dfs(1,0,0);
    dfs(1,0,1);

    for(int up=0;up<2;++up) {
        for(int i=0;i<=n;++i) {
            for(int j=0;j<=n;++j) {
                int lca = getAnc(device[i][up], device[j][up],up).first;
                preSet[i][j][up] = depth[device[j][up]][up] - depth[lca][up];
            }
        }
    }
    memset(dp,-1,sizeof(dp));
    printf("%d\n", a+b-2 - min(solveDp(1,0,1,1,n), solveDp(1,0,0,1,n)));
}

void solve() {
    // init();
    // int t;
    // scanf("%d",&t);
    // while(t--)
    solve2();
}

inline bool exists_test0 (const std::string& name);
inline bool exists_test1 (const std::string& name);
int main() {
  solve();
  return 0;
}

/*
0. Enough array nsize? Enough array nsize? Integer overflow?

1. Think TWICE, Code ONCE!
Are there any counterexamples to your algo?

2. Be careful about the BOUNDARIES!
N=1? P=1? Something about 0?

3. Do not make STUPID MISTAKES!
Time complexity? Memory usage? Precision error?

4. Be careful to use wrong variable.
*/
inline bool exists_test0 (const std::string& name) {
    ifstream f(name.c_str());
    return f.good();
}

inline bool exists_test1 (const std::string& name) {
    if (FILE *file = fopen(name.c_str(), "r")) {
        fclose(file);
        return true;
    } else {
        return false;
    }
}


Comments

Submit
0 Comments
More Questions

1002. Find Common Characters
1602A - Two Subsequences
1555A - PizzaForces
1607B - Odd Grasshopper
1084A - The Fair Nut and Elevator
1440B - Sum of Medians
1032A - Kitchen Utensils
1501B - Napoleon Cake
1584B - Coloring Rectangles
1562B - Scenes From a Memory
1521A - Nastia and Nearly Good Numbers
208. Implement Trie
1605B - Reverse Sort
1607C - Minimum Extraction
1604B - XOR Specia-LIS-t
1606B - Update Files
1598B - Groups
1602B - Divine Array
1594B - Special Numbers
1614A - Divan and a Store
2085. Count Common Words With One Occurrence
2089. Find Target Indices After Sorting Array
2090. K Radius Subarray Averages
2091. Removing Minimum and Maximum From Array
6. Zigzag Conversion
1612B - Special Permutation
1481. Least Number of Unique Integers after K Removals
1035. Uncrossed Lines
328. Odd Even Linked List
1219. Path with Maximum Gold