Submission #26729

# Submission time Handle Problem Language Result Execution time Memory
26729 2017-07-05T10:39:19 Z model_code Inspection (POI11_ins) C++14
100 / 100
2533 ms 113740 KB
/*************************************************************************
 *                                                                       *
 *                    XVIII Olimpiada Informatyczna                      *
 *                                                                       *
 *   Zadanie:           Inspekcja                                        *
 *   Autor:             Miroslaw Michalski                               *
 *   Zlozonosc czasowa: O(n)                                             *
 *   Opis:              Rozwiazanie wzorcowe - sprytniejsze              *
 *                                                                       *
 *************************************************************************/

#include <cstdio>
#include <vector>
#include <queue>
#include <cassert>

typedef long long LL; // tylko po to aby sprawdzic jak zachowa sie dla intow

const int MAXN = 1000123;
const int NOANS = -1;


int deg[MAXN];
std::vector<int> v[MAXN];
int n;

bool used[MAXN];
int myDeg[MAXN], father[MAXN], sizeOfSubtree[MAXN], depth[MAXN], maxSubtree[MAXN];
LL cost[MAXN];

void dfs(int x) {
    used[x] = true;
    for(size_t i = 0; i < v[x].size(); i++) if (!used[v[x][i]]) {
        father[v[x][i]] = x;
        dfs(v[x][i]);
    }
}

std::vector<int> getCands(int root) {
    std::vector<int> cands;
    for(int i = 0; i < n; i++) {
        myDeg[i] = deg[i];
        used[i] = false;
        father[i] = -1;
        
        sizeOfSubtree[i] = 1;
        maxSubtree[i] = 0;
    }
    dfs(root);

    std::queue<int> q;
    for(int i = 0; i < n; i++) if (myDeg[i] == 1) {
        q.push(i);
    }
    while (!q.empty()) {
        int wz1 = q.front(); q.pop();
        myDeg[father[wz1]]--;
        if (std::max(n - sizeOfSubtree[wz1], maxSubtree[wz1]) <= n/2) {
            cands.push_back(wz1);
        }
        
        sizeOfSubtree[father[wz1]] += sizeOfSubtree[wz1];
        maxSubtree[father[wz1]] = std::max(maxSubtree[father[wz1]], sizeOfSubtree[wz1]);

        if (myDeg[father[wz1]] == 1 && father[wz1] != -1) {
            q.push(father[wz1]);
        }
    }
    return cands;
}

LL anal(int root) {
// liczymy odpowiedz dla root'a max. poddrzewo == n/2
    for(int i = 0; i < n; i++) {
        myDeg[i] = deg[i];
        used[i] = false;
        father[i] = -1;
        
        sizeOfSubtree[i] = 1;
        cost[i] = 0;
        depth[i] = 0;
    }
    dfs(root);

    std::queue<int> q;
    for(int i = 0; i < n; i++) if (myDeg[i] == 1) {
        q.push(i);
    }

    while (!q.empty()) {
        int wz1 = q.front(); q.pop();
        myDeg[father[wz1]]--;
        
        sizeOfSubtree[father[wz1]] += sizeOfSubtree[wz1];
        cost[father[wz1]] += (2L * sizeOfSubtree[wz1] + cost[wz1]);
        depth[father[wz1]] = std::max(depth[father[wz1]], depth[wz1] + 1);

        if (myDeg[father[wz1]] == 1 && father[wz1] != -1) {
            q.push(father[wz1]);
        }
    }

    int maxDepth = 0;
    for(size_t i = 0; i < v[root].size(); i++) {
        maxDepth = std::max(maxDepth, depth[v[root][i]]);
    }
    for(size_t i = 0; i < v[root].size(); i++) {
        if (sizeOfSubtree[v[root][i]] ==  n/2) {
            maxDepth = depth[v[root][i]];
        }
    }
    return cost[root] - (maxDepth + 1);
}

int main() {
    int a, b;
    scanf("%d", &n);
    if (n == 1) {
        printf("0\n");
        return 0;
    }
    for(int i = 0; i < n - 1; i++) {
        scanf("%d %d", &a, &b);
        a--; b--;
        v[a].push_back(b);
        v[b].push_back(a);
        deg[a]++;
        deg[b]++;
    }

    std::vector<int> getCandidates = getCands(n - 1);
    if (getCandidates.size() == 1) {
        int a = getCandidates[0]; 
        for(int i = 0; i < a; i++) {
            printf("%d\n", NOANS);
        }
        printf("%lld\n", anal(a));
        for(int i = a + 1; i < n; i++) {
            printf("%d\n", NOANS);
        }
    } else if (getCandidates.size() == 2) {
        int a = getCandidates[0], b = getCandidates[1];
        if (a > b) std::swap(a, b);
        for(int i = 0; i < a; i++) {
            printf("%d\n", NOANS);
        }
        printf("%lld\n", anal(a));
        for(int i = a + 1; i < b; i++) {
            printf("%d\n", NOANS);
        }
        printf("%lld\n", anal(b));
        for(int i = b + 1; i < n; i++) {
            printf("%d\n", NOANS);
        }
    } else {
        assert(false);
    }
    return 0;
}

Compilation message

ins.cpp: In function 'int main()':
ins.cpp:117:20: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%d", &n);
                    ^
ins.cpp:123:31: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
         scanf("%d %d", &a, &b);
                               ^
# Verdict Execution time Memory Grader output
1 Correct 6 ms 57604 KB Output is correct
2 Correct 6 ms 57604 KB Output is correct
3 Correct 6 ms 57604 KB Output is correct
4 Correct 3 ms 57604 KB Output is correct
5 Correct 6 ms 57604 KB Output is correct
6 Correct 6 ms 57604 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 3 ms 57604 KB Output is correct
2 Correct 3 ms 57604 KB Output is correct
3 Correct 3 ms 57604 KB Output is correct
4 Correct 3 ms 57604 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 9 ms 57736 KB Output is correct
2 Correct 3 ms 57736 KB Output is correct
3 Correct 6 ms 57736 KB Output is correct
4 Correct 9 ms 57736 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 29 ms 58264 KB Output is correct
2 Correct 16 ms 58376 KB Output is correct
3 Correct 26 ms 58608 KB Output is correct
4 Correct 19 ms 58264 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 43 ms 58924 KB Output is correct
2 Correct 43 ms 59268 KB Output is correct
3 Correct 69 ms 59728 KB Output is correct
4 Correct 46 ms 58792 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 163 ms 61052 KB Output is correct
2 Correct 109 ms 62080 KB Output is correct
3 Correct 93 ms 63124 KB Output is correct
4 Correct 99 ms 60788 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 1076 ms 74800 KB Output is correct
2 Correct 1002 ms 80112 KB Output is correct
3 Correct 1039 ms 85704 KB Output is correct
4 Correct 806 ms 73496 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 2533 ms 92056 KB Output is correct
2 Correct 2483 ms 102872 KB Output is correct
3 Correct 2266 ms 113740 KB Output is correct
4 Correct 1809 ms 89260 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 2256 ms 92056 KB Output is correct
2 Correct 2446 ms 102872 KB Output is correct
3 Correct 2406 ms 113740 KB Output is correct
4 Correct 1839 ms 89260 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 2449 ms 92056 KB Output is correct
2 Correct 2016 ms 102872 KB Output is correct
3 Correct 2253 ms 113736 KB Output is correct
4 Correct 1986 ms 89260 KB Output is correct