QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#266934 | #7216. Boxes on tree | kyEEcccccc | WA | 1ms | 6136kb | C++14 | 3.3kb | 2023-11-26 20:02:58 | 2023-11-26 20:02:58 |
Judging History
answer
// Author: kyEEcccccc
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
using ULL = unsigned long long;
#define F(i, l, r) for (int i = (l); i <= (r); ++i)
#define FF(i, r, l) for (int i = (r); i >= (l); --i)
#define MAX(a, b) ((a) = max(a, b))
#define MIN(a, b) ((a) = min(a, b))
#define SZ(a) ((int)((a).size()) - 1)
constexpr int N = 505, K = 9;
int n;
int tar[N];
vector<int> chi[N];
int par[N], dep[N];
int dfn[N], idfn[N], cur_dfn;
array<int, 2> lca_mn[505][N];
void init_tree(int u)
{
dfn[u] = ++cur_dfn;
idfn[dfn[u]] = u;
for (auto v : chi[u])
{
par[v] = u;
chi[v].erase(find(chi[v].begin(), chi[v].end(), u));
dep[v] = dep[u] + 1;
init_tree(v);
}
}
int get_lca(int u, int v)
{
if (u == v) return u;
u = dfn[u], v = dfn[v];
if (u > v) swap(u, v);
int k = __lg(v - u);
return par[min(lca_mn[k][u + 1], lca_mn[k][v - (1 << k) + 1])[1]];
}
int get_dis(int u, int v)
{
int lca = get_lca(u, v);
return dep[u] + dep[v] - dep[lca] * 2;
}
bool tg[N], vv[N];
struct Cir
{
vector<int> pts;
int rt;
};
vector<Cir> cs;
int dd[N][N];
vector<array<int, 3>> ed;
struct Dsu
{
int ff[N], sz[N];
void init(int nn)
{
iota(ff + 1, ff + nn + 1, 1);
fill(sz + 1, sz + nn + 1, 1);
}
int get_anc(int u) { return u == ff[u] ? u : (ff[u] = get_anc(ff[u])); }
bool merge(int u, int v)
{
u = get_anc(u), v = get_anc(v);
if (u == v) return false;
if (sz[u] > sz[v]) swap(u, v);
sz[v] += sz[u];
ff[u] = v;
return true;
}
} dsu;
signed main(void)
{
// freopen(".in", "r", stdin);
// freopen(".out", "w", stdout);
ios::sync_with_stdio(0), cin.tie(nullptr);
cin >> n;
F(i, 1, n) cin >> tar[i];
F(i, 1, n - 1)
{
int u, v;
cin >> u >> v;
chi[u].push_back(v);
chi[v].push_back(u);
}
par[1] = 0;
dep[1] = 1;
init_tree(1);
F(i, 1, n) lca_mn[0][dfn[i]] = {dep[i], i};
F(k, 1, K - 1) F(i, 1, n - (1 << k) + 1)
lca_mn[k][i] = min(lca_mn[k - 1][i], lca_mn[k - 1][i + (1 << (k - 1))]);
cs.push_back({{1}, 1});
int ans = 0;
F(i, 1, n)
{
if (vv[i] || tar[i] == i) continue;
int p = i;
F(j, 1, n) tg[j] = false;
while (!vv[p])
{
int u = p, v = tar[p], lca = get_lca(u, v);
ans += get_dis(u, v);
while (u != lca)
{
tg[u] = true;
u = par[u];
}
while (v != lca)
{
tg[v] = true;
v = par[v];
}
tg[lca] = true;
vv[p] = true;
p = tar[p];
}
cs.push_back({{}, 0});
F(j, 1, n)
{
if (!tg[j]) continue;
cs.back().pts.push_back(j);
if (cs.back().rt == 0 || dep[cs.back().rt] > dep[j]) cs.back().rt = j;
}
}
memset(dd, 0x3f, sizeof (dd));
F(i, 1, SZ(cs))
{
F(j, 1, n) tg[j] = false;
for (auto x : cs[i].pts)
{
tg[x] = true;
}
F(j, 0, i - 1)
{
dd[i][j] = INT_MAX / 2;
for (auto x : cs[j].pts)
{
if (tg[x]) { dd[i][j] = 0; break; }
MIN(dd[i][j], get_dis(x, cs[i].rt));
}
if (dd[i][j] == 0) continue;
for (auto x : cs[i].pts)
{
MIN(dd[i][j], get_dis(cs[j].rt, x));
}
ed.push_back({dd[i][j], i + 1, j + 1});
}
}
sort(ed.begin(), ed.end());
dsu.init(cs.size());
for (auto ee : ed)
{
if (dsu.merge(ee[1], ee[2]))
{
ans += ee[0] * 2;
}
}
cout << ans << endl;
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 4588kb
input:
3 1 3 2 1 2 2 3
output:
4
result:
ok 1 number(s): "4"
Test #2:
score: -100
Wrong Answer
time: 1ms
memory: 6136kb
input:
4 2 1 4 3 1 3 3 2 3 4
output:
8
result:
wrong answer 1st numbers differ - expected: '6', found: '8'