Submission #602774

#TimeUsernameProblemLanguageResultExecution timeMemory
602774boris_mihovThe Xana coup (BOI21_xanadu)C++14
10 / 100
179 ms86476 KiB
#include <iostream>
#include <vector>

typedef long long llong;
const int MAXN = 100000 + 10;
const int INF  = 1e9;

int dp[MAXN][2][2][2];
bool bl[MAXN][2][2][2];
std::vector <int> g[MAXN];
std::vector <int> dp2[MAXN][2][2][2][2];
bool state[MAXN];
int n;

int f(int node, int p, bool should, bool incoming, bool currTurned)
{
    if (g[node].size() - (p != 0) == 0)
    {
        if ((incoming ^ should) != state[node]) return INF;
        return should;
    }

    if (bl[node][should][incoming][currTurned]) 
    {
        return dp[node][should][incoming][currTurned];
    }

    bl[node][should][incoming][currTurned] = true;
    if (should)
    {
        return dp[node][should][incoming][currTurned] = f(node, p, 0, incoming, 1) + 1;
    }

    dp2[node][should][incoming][currTurned][0].resize(g[node].size() - (p != 0) + 1);
    dp2[node][should][incoming][currTurned][1].resize(g[node].size() - (p != 0) + 1);

    for (int &i : g[node])
    {
        if (i == p)
        {
            std::swap(i, g[node].back());
            break;
        }
    }

    bool wantedParity = currTurned ^ incoming ^ state[node];
    dp2[node][should][incoming][currTurned][wantedParity][g[node].size() - (p != 0)] = 0;
    dp2[node][should][incoming][currTurned][!wantedParity][g[node].size() - (p != 0)] = INF;
    
    for (int i = g[node].size() - 1 - (p != 0) ; i >= 0 ; --i)
    {
        for (int parity = 0 ; parity < 2 ; ++parity)
        {
            dp2[node][should][incoming][currTurned][parity][i] = dp2[node][should][incoming][currTurned][parity][i + 1] + f(g[node][i], node, 0, currTurned, 0);
            dp2[node][should][incoming][currTurned][parity][i] = std::min(dp2[node][should][incoming][currTurned][parity][i],
                                                              dp2[node][should][incoming][currTurned][!parity][i + 1] + f(g[node][i], node, 1, currTurned, 0));
        }
    }

    return dp[node][should][incoming][currTurned] = dp2[node][should][incoming][currTurned][0][0];
}

void solve()
{
   int res = std::min(f(1, 0, 0, 0, 0), f(1, 0, 1, 0, 0));
   if (res >= MAXN) std::cout << "impossible\n";
   else std::cout << res << '\n';
}

void read()
{
    int x, y;
    std::cin >> n;
    for (int i = 2 ; i <= n ; ++i)
    {
        std::cin >> x >> y;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    
    for (int i = 1 ; i <= n ; ++i)
    {
        std::cin >> state[i];
    }
}

void fastIO()
{
    std::ios_base :: sync_with_stdio(0);
    std::cout.tie(nullptr);
    std::cin.tie(nullptr);
}

int main()
{
    fastIO();
    read();
    solve();
    
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...