제출 #472194

#제출 시각아이디문제언어결과실행 시간메모리
472194prvocisloMergers (JOI19_mergers)C++17
100 / 100
883 ms75404 KiB
#include <iostream>
#include <vector>
using namespace std;

const int maxn = 5e5 + 5;
int n, k, t = 0;
int l[maxn], r[maxn];
int ls[maxn], rs[maxn], s[maxn];
int l2[maxn], r2[maxn];
vector<int> g[maxn];
bool c[maxn];
void dfs_time(int u, int p = -1)
{
	l[u] = t++;
	for (int v : g[u]) if (v != p) dfs_time(v, u);
	r[u] = t - 1;
}
void dfs_critical(int u, int p = -1)
{
	l2[u] = min(l[u], ls[s[u]]);
	r2[u] = max(r[u], rs[s[u]]);
	for (int v : g[u]) if (v != p)
	{
		dfs_critical(v, u);
		l2[u] = min(l2[u], l2[v]);
		r2[u] = max(r2[u], r2[v]);
	}
	if (u && l[u] == l2[u] && r[u] == r2[u])
		c[u] = true;
}
int cuts = 0;
bool dfs_cover(int u, int p = -1)
{
	bool is_covered = false;
	for (int v : g[u]) if (v != p) is_covered |= dfs_cover(v, u);
	if (!is_covered && c[u])
	{
		cuts++;
		return true;
	}
	return is_covered;
}
int dfs_cuts_root_can_reach(int u, int p = -1)
{
	if (c[u]) return 1;
	int sum = 0;
	for (int v : g[u]) if (v != p) sum += dfs_cuts_root_can_reach(v, u);
	return sum;
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin >> n >> k;
	for (int i = 0, a, b; i < n - 1; i++)
	{
		cin >> a >> b;
		g[--a].push_back(--b);
		g[b].push_back(a);
	}
	dfs_time(0);
	for (int i = 0; i < k; i++) ls[i] = 1e9, rs[i] = -1e9;
	for (int i = 0; i < n; i++)
	{
		cin >> s[i]; s[i]--;
		ls[s[i]] = min(ls[s[i]], l[i]);
		rs[s[i]] = max(rs[s[i]], r[i]);
	}
	dfs_critical(0);
	dfs_cover(0);
	int ans = (cuts + 1) / 2;
	int cnt = dfs_cuts_root_can_reach(0);
	if (cuts % 2 == 0 && cnt == 1) ans++; // musime to este spojit aj s korenom
	cout << ans << "\n";
	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...