Hướng dẫn giải của Điều Quân


Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
#include<bits/stdc++.h>

#define int long long

#define vc vector
#define pb emplace_back
#define pii pair<int, int>
#define mkp make_pair
#define rep(i, a, b) for(int i = (a); i <= (b); ++i)
#define lep(i, a, b) for(int i = (a); i >= (b); --i)

using namespace std;

mt19937 gen(chrono::system_clock::now().time_since_epoch().count());

inline int read() {
        int x = 0, w = 0;
        char ch = getchar();
        while(!isdigit(ch)) w |= (ch == '-'), ch = getchar();
        while(isdigit(ch)) x = x * 10 + (ch ^ 48), ch = getchar();
        return w ? -x : x;
}

const int N = 5e5 + 5;

int n, m, ans, a[N], b[N], f[N];
int loop[N], cnt;
int dfn[N], low[N], stk[N], DFN, idx, topf;
vc <int> G[N], T[N];

inline void tarjan (int x) {
        dfn[x] = low[x] = ++ DFN; stk[++ topf] = x;
        for (auto y : G[x])
                if (! dfn[y]) {
                        tarjan (y);
                        low[x] = min (low[x], low[y]);
                        if (low[y] >= dfn[x]) {
                                ++ idx; int z;
                                T[idx].pb (x); T[x].pb (idx);
                                do { z = stk[topf --]; T[idx].pb (z); T[z].pb (idx); } while (z != y);
                        }
                }
                else low[x] = min (low[x], dfn[y]);
}

inline int dfs (int x, int fa) {
        int sum = a[x] - b[x];
        for (auto y : T[x]) if (y != fa) sum += dfs (y, x);
        // square node
        if (x > n) {
                f[fa] = - sum; 
                cnt = 0;
                int res = 0;
                for (auto y : T[x]) {
                        res += f[y];
                        loop[cnt ++] = res;
                }
                sort (loop, loop + cnt);
                int mid = loop[cnt / 2];
                rep (i, 0, cnt - 1) ans += abs (loop[i] - mid);
        }
        return f[x] = sum;
}

inline void testcase () {
        n = read (); m = read ();

        ans = 0; DFN = topf = 0; idx = n;
        rep (i, 0, 2 * n) G[i].clear (), T[i].clear (), dfn[i] = a[i] = b[i] = 0;

        rep (i, 1, n) a[i] = read ();
        rep (i, 1, n) b[i] = read ();
        for (int i = 1, x, y; i <= m; i ++) 
                x = read (), y = read (), G[x].pb (y), G[y].pb (x);
        tarjan (1);
        dfs (1, 0);

        printf ("%lld\n", ans);
}

signed main() {
        int t = read (); while (t --) testcase ();
        return 0;
}

Đang tải...