제출 #1337351

#제출 시각아이디문제언어결과실행 시간메모리
1337351hauserlMousetrap (CEOI17_mousetrap)C++20
45 / 100
372 ms86544 KiB
#include <bits/stdc++.h>
#define ll long long
using namespace std;

ll n,t,m; 

vector<vector<ll>> adj;
vector<ll> countSubtrees;
vector<ll> dp;
vector<ll> parent;
vector<bool> onMainPath;
vector<ll> mainPath;

bool dfs(int u, int p) {
    parent[u] = p;
    bool isOnMP = u == m;
    

    ll max1 = 0;
    ll max2 = 0;

    for (const auto& v : adj[u]) {
        if (v == p) continue;
        isOnMP |= dfs(v, u);

        if (dp[v] > max1) {
            max2 = max1;
            max1 = dp[v];
        } else if (dp[v] > max2) {
            max2 = dp[v];
        }
    } 

    // dp
    if (adj[u].size() == 1) dp[u] = 0;
    else if (adj[u].size() == 2) dp[u] = 1;
    else dp[u] = max2 + adj[u].size() - 2 + 1;

    if (isOnMP) mainPath.push_back(u);

    return onMainPath[u] = isOnMP;
}

bool checkMid(ll x) {
    if (countSubtrees[mainPath[0]] > x) return false;

    ll blocks = 0;
    for (ll i = 0; i < mainPath.size()-1; i++) {
        if (mainPath[i] == t) break;
        
        int dangerousChildren = 0;
        for (const auto& v : adj[mainPath[i]]) {
            if (onMainPath[v] || v == parent[mainPath[i]]) continue;
            if (dp[v] + countSubtrees[mainPath[i]] > x) dangerousChildren++;
        }

        blocks += dangerousChildren;

        if (blocks > i + 1) return false;
    }

    return blocks <= x;
}

int main() {

    scanf("%lld %lld %lld",&n,&t,&m);
    adj.resize(n+1, vector<ll>());
    countSubtrees.resize(n+1, 0);
    dp.resize(n+1, -1);
    parent.resize(n+1, -1);
    onMainPath.resize(n+1, false);

    for (int i = 1; i < n; i++) {
        ll a,b; scanf("%lld %lld",&a,&b);
        adj[a].push_back(b);
        adj[b].push_back(a);
    }

    dfs(t, -1);

    // subtrees
    for (int i = mainPath.size() -1; i >= 0; i--) {
        ll u = mainPath[i];
        ll tN = adj[u].size();
        if (u == m) countSubtrees[u] = tN - 1 + countSubtrees[parent[u]];
        else if (u == t) countSubtrees[u] = 0;
        else countSubtrees[u] = tN - 2 + countSubtrees[parent[u]];
    }
    



    ll l = -1;
    ll r = n +1;

    while (l + 1 < r) {
        ll mid = l + (r-l)/2;

        if (checkMid(mid)) r = mid;
        else l = mid;
    }

    printf("%lld", r);

    return 0;
}

컴파일 시 표준 에러 (stderr) 메시지

mousetrap.cpp: In function 'int main()':
mousetrap.cpp:67:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   67 |     scanf("%lld %lld %lld",&n,&t,&m);
      |     ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
mousetrap.cpp:75:22: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   75 |         ll a,b; scanf("%lld %lld",&a,&b);
      |                 ~~~~~^~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...