답안 #947925

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
947925 2024-03-17T09:22:31 Z danikoynov Designated Cities (JOI19_designated_cities) C++14
23 / 100
2000 ms 31148 KB
#include<bits/stdc++.h>
#define endl '\n'

using namespace std;
typedef long long ll;

void speed()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
}

const int maxn = 2e5 + 10;

struct edge
{
    int v, u;
    ll c, d;

    edge(int _v = 0, int _u = 0, ll _c = 0, ll _d = 0)
    {
        v = _v;
        u = _u;
        c = _c;
        d = _d;
    }
} edges[maxn];


int n;
vector < pair < int, int > > adj[maxn];

ll sum_all = 0;
void input()
{
    cin >> n;
    for (int i = 1; i < n; i ++)
    {
        cin >> edges[i].v >> edges[i].u >> edges[i].c >> edges[i].d;
        adj[edges[i].v].push_back({edges[i].u, i});
        adj[edges[i].u].push_back({edges[i].v, i});
        sum_all += edges[i].c + edges[i].d;
    }
}

const ll inf = 1e18;

ll single;
ll sub[maxn];
void calc(int v, int p)
{
    sub[v] = 0;
    for (pair < int, int > nb : adj[v])
    {
        int u = nb.first;
        if (u == p)
            continue;

        calc(u, v);
        if (v == edges[nb.second].v)
            sub[v] += edges[nb.second].d; //cout << "edge " << v << " : " << u << " : " << edges[nb.second].d << endl;
        else
            sub[v] += edges[nb.second].c;
        sub[v] += sub[u];
    }
    //cout << "calc " << v << " " << sub[v] << endl;
}

void single_dfs(int v, int p, ll val)
{
    single = max(single, val);
    ///cout << v << " : " << val << endl;
    for (pair < int, int > nb : adj[v])
    {
        int u = nb.first;
        if (u == p)
            continue;

        ll cur;
        if (v == edges[nb.second].v)
            cur = edges[nb.second].c - edges[nb.second].d;
        else
            cur = edges[nb.second].d - edges[nb.second].c;

        single_dfs(u, v, val + cur);
    }
}

void solve_single()
{
    calc(1, -1);
    single_dfs(1, -1, sub[1]);
    single = sum_all - single;
}

ll depth[maxn];
int ord[maxn], timer;
int tin[maxn], tout[maxn];
int par[maxn], ridx[maxn], marked[maxn];

void do_math(int v, int p, int id)
{
    par[v] = p;
    ridx[v] = id;
    ord[++ timer] = v;
    tin[v] = timer;
    for (pair < int, int > nb : adj[v])
    {
        int u = nb.first, idx = nb.second;
        if (u == p)
            continue;
        ll val;
        if (v == edges[idx].v)
            val = edges[idx].c;
        else
            val = edges[idx].d;
        if (marked[idx])
            val = 0;
        depth[u] = depth[v] + val;
        do_math(u, v, idx);
    }
    tout[v] = timer;
}

bool in_subtree(int v, int u)
{
    return (tin[v] <= tin[u] && tout[v] >= tout[u]);
}

void go_mark(int v)
{
    while(par[v] != -1)
    {

        marked[ridx[v]] = 1;
        v = par[v];
    }
}

int find_root()
{
    int root = 1;
    while(true)
    {

        timer = 0;
        depth[root] = 0;
        for (int i = 1; i <= n; i ++)
            marked[i] = 0;
        do_math(root, - 1, - 1);

        int d = 1;
        for (int i = 1; i <= n; i ++)
            if (depth[i] > depth[d])
                d = i;

        go_mark(d);

        timer = 0;
        depth[root] = 0;
        do_math(root, - 1, - 1);

        int f = 1;
        for (int i = 1; i <= n; i ++)
            if (depth[i] > depth[f])
                f = i;

        bool done = true;
        for (pair < int, int > nb : adj[root])
        {
            int u = nb.first;
            if (in_subtree(u, d) && in_subtree(u, f))
            {
                done = false;
                root = u;
                break;
            }
        }

        if (done)
            break;


    }

    return root;
}

ll values[maxn];
void clean(int v)
{
    while(par[v] != -1)
    {
        if (marked[ridx[v]])
            break;
        marked[ridx[v]] = 1;
        ll cur;
        if (edges[ridx[v]].u == v)
            cur = edges[ridx[v]].c;
        else
            cur = edges[ridx[v]].d;
        for (int i = tin[v]; i <= tout[v]; i ++)
            depth[ord[i]] -= cur;
        v = par[v];
    }
}
void simulate(int root)
{
    calc(root, -1);

    timer = 0;
    depth[root] = 0;
    for (int i = 1; i <= n; i ++)
        marked[i] = 0;
    do_math(root, - 1, - 1);

    int pivot = 0;
    ll so_far = sum_all - sub[root];
    while(true)
    {
        int d = 1;
        for (int i = 1; i <= n; i ++)
            if (depth[i] > depth[d])
            d = i;

        if (depth[d] == 0)
            break;
        pivot ++;
        so_far -= depth[d];
        clean(d);
        values[pivot] = so_far;
    }

    int q;
    cin >> q;
    for (int i = 1; i <= q; i ++)
    {
        int e;
        cin >> e;
        if (e == 1)
        {
            cout << single << endl;
            continue;
        }
        if (e > pivot)
            e = pivot;
        cout << values[e] << endl;
    }
}
void solve()
{
    input();
    solve_single();
    int root = find_root();
    simulate(root);

}

int main()
{
    speed();
    int t = 1;
    ///cin >> t;
    while(t --)
        solve();
    return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 9820 KB Output is correct
2 Correct 4 ms 9820 KB Output is correct
3 Correct 4 ms 9820 KB Output is correct
4 Correct 4 ms 9916 KB Output is correct
5 Correct 4 ms 9820 KB Output is correct
6 Correct 4 ms 9820 KB Output is correct
7 Correct 4 ms 9820 KB Output is correct
8 Correct 4 ms 9820 KB Output is correct
9 Correct 4 ms 9916 KB Output is correct
10 Correct 4 ms 9820 KB Output is correct
11 Correct 4 ms 9820 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 5 ms 9972 KB Output is correct
2 Execution timed out 2087 ms 31104 KB Time limit exceeded
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 10072 KB Output is correct
2 Execution timed out 2053 ms 31148 KB Time limit exceeded
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 9820 KB Output is correct
2 Correct 4 ms 9820 KB Output is correct
3 Correct 4 ms 9820 KB Output is correct
4 Correct 4 ms 9916 KB Output is correct
5 Correct 4 ms 9820 KB Output is correct
6 Correct 4 ms 9820 KB Output is correct
7 Correct 4 ms 9820 KB Output is correct
8 Correct 4 ms 9820 KB Output is correct
9 Correct 4 ms 9916 KB Output is correct
10 Correct 4 ms 9820 KB Output is correct
11 Correct 4 ms 9820 KB Output is correct
12 Correct 4 ms 9820 KB Output is correct
13 Correct 7 ms 10076 KB Output is correct
14 Correct 6 ms 10076 KB Output is correct
15 Correct 9 ms 10076 KB Output is correct
16 Correct 6 ms 10076 KB Output is correct
17 Correct 7 ms 10076 KB Output is correct
18 Correct 6 ms 10076 KB Output is correct
19 Correct 7 ms 10008 KB Output is correct
20 Correct 7 ms 9960 KB Output is correct
21 Correct 6 ms 10012 KB Output is correct
22 Correct 7 ms 10088 KB Output is correct
23 Correct 7 ms 10076 KB Output is correct
24 Correct 7 ms 9960 KB Output is correct
25 Correct 7 ms 10076 KB Output is correct
26 Correct 7 ms 10076 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 5 ms 9972 KB Output is correct
2 Execution timed out 2087 ms 31104 KB Time limit exceeded
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 9820 KB Output is correct
2 Correct 4 ms 9820 KB Output is correct
3 Correct 4 ms 9820 KB Output is correct
4 Correct 4 ms 9916 KB Output is correct
5 Correct 4 ms 9820 KB Output is correct
6 Correct 4 ms 9820 KB Output is correct
7 Correct 4 ms 9820 KB Output is correct
8 Correct 4 ms 9820 KB Output is correct
9 Correct 4 ms 9916 KB Output is correct
10 Correct 4 ms 9820 KB Output is correct
11 Correct 4 ms 9820 KB Output is correct
12 Correct 5 ms 9972 KB Output is correct
13 Execution timed out 2087 ms 31104 KB Time limit exceeded
14 Halted 0 ms 0 KB -