Submission #545910

#TimeUsernameProblemLanguageResultExecution timeMemory
545910rainboyMousetrap (CEOI17_mousetrap)C11
100 / 100
887 ms159604 KiB
#include <stdio.h>
#include <stdlib.h>

#define N	1000000
#define INF	0x3f3f3f3f

int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; }

unsigned int X = 12345;

int rand_() {
	return (X *= 3) >> 1;
}

int *ej[N], eo[N];

void append(int i, int j) {
	int o = eo[i]++;

	if (o >= 2 && (o & o - 1) == 0)
		ej[i] = (int *) realloc(ej[i], o * 2 * sizeof *ej[i]);
	ej[i][o] = j;
}

int dp[N];

void dfs_(int p, int i, int k) {
	int o, mx1, mx2;

	k += eo[i] - 1, mx1 = mx2 = k;
	for (o = eo[i]; o--; ) {
		int j = ej[i][o];

		if (j != p) {
			dfs_(i, j, k);
			if (mx1 < dp[j])
				mx2 = mx1, mx1 = dp[j];
			else if (mx2 < dp[j])
				mx2 = dp[j];
		}
	}
	dp[i] = mx2;
}

void sort(int *ii, int l, int r) {
	while (l < r) {
		int i = l, j = l, k = r, i_ = ii[l + rand_() % (r - l)], tmp;

		while (j < k)
			if (dp[ii[j]] == dp[i_])
				j++;
			else if (dp[ii[j]] > dp[i_]) {
				tmp = ii[i], ii[i] = ii[j], ii[j] = tmp;
				i++, j++;
			} else {
				k--;
				tmp = ii[j], ii[j] = ii[k], ii[k] = tmp;
			}
		sort(ii, l, i);
		l = k;
	}
}

int qu[N], gg[N], jj[N], n, m, l, ans; char path[N];

int solve() {
	int g, g_, h;

	for (g = 0, g_ = 0, h = 0; g <= l; g++) {
		while (h < m && dp[jj[h]] + g_ <= ans) {
			h++;
			if (h < m && gg[jj[h]] != gg[jj[h - 1]])
				g_ = g;
		}
		if (h == m)
			return 1;
		if (gg[jj[h]] < g || g == ans)
			return 0;
		h++;
		if (h < m && gg[jj[h]] != gg[jj[h - 1]])
			g_ = g + 1;
	}
	return 1;
}

int dfs(int p, int i, int t) {
	int o;

	qu[l++] = i, path[i] = 1;
	if (i == t) {
		int d, g, lower, upper;

		l--, d = 0;
		for (g = 0; g < l; g++) {
			i = qu[g];
			d += eo[i] - (g == 0 ? 1 : 2);
		}
		m = 0;
		for (g = 0; g < l; g++) {
			int m_;

			i = qu[g];
			m_ = m;
			for (o = eo[i]; o--; ) {
				int j = ej[i][o];

				if (!path[j]) {
					dfs_(i, j, d);
					gg[j] = g, jj[m_] = j, m_++;
				}
			}
			sort(jj, m, m_);
			m = m_;
			d -= eo[i] - (g == 0 ? 1 : 2);
		}
		lower = -1, upper = n;
		while (upper - lower > 1) {
			ans = (lower + upper) / 2;
			if (solve())
				upper = ans;
			else
				lower = ans;
		}
		ans = upper;
		return 1;
	}
	for (o = eo[i]; o--; ) {
		int j = ej[i][o];

		if (j != p && dfs(i, j, t))
			return 1;
	}
	l--, path[i] = 0;
	return 0;
}

int main() {
	int t, m, h, i, j;

	scanf("%d%d%d", &n, &t, &m), t--, m--;
	if (m == t) {
		printf("0\n");
		return 0;
	}
	for (i = 0; i < n; i++)
		ej[i] = (int *) malloc(2 * sizeof *ej[i]);
	for (h = 0; h < n - 1; h++) {
		scanf("%d%d", &i, &j), i--, j--;
		append(i, j), append(j, i);
	}
	dfs(-1, m, t);
	printf("%d\n", ans);
	return 0;
}

Compilation message (stderr)

mousetrap.c: In function 'append':
mousetrap.c:21:23: warning: suggest parentheses around '-' in operand of '&' [-Wparentheses]
   21 |  if (o >= 2 && (o & o - 1) == 0)
      |                     ~~^~~
mousetrap.c: In function 'main':
mousetrap.c:141:2: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  141 |  scanf("%d%d%d", &n, &t, &m), t--, m--;
      |  ^~~~~~~~~~~~~~~~~~~~~~~~~~~
mousetrap.c:149:3: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  149 |   scanf("%d%d", &i, &j), i--, j--;
      |   ^~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...