[メーターニンニク旅客T2237]魔法の木_

マジック

効果の対象

データ範囲


問題の解決策

本当に楽しい質問

矛盾することにより、すべての葉が選択しなければならなかったし、すべての葉が合法的な選挙を持って見つけることができます。

そこで我々は、一回の操作後の葉の少なくとも数となるようにするためにあります。

これは、それを取得する方法ですか?

我々は、接続された2点のエッジが($ D_I $ $ iが$程度の点を表し、$ D_X \ルd_y $を設定することを望むかもしれない)場合、$ X $と$ Yの$、ということが見出さ満たされます。

$ D_y \ GE 3 $と$ D_X \ GE 3 $が、その後、葉は$することができます - = $ 2

$ d_y \ GE 3 $と$ D_X \ル2 $場合、その葉は$することができます - = $ 1。

$ $など$ -2 $ -1まで見るために、それぞれの側を列挙〜

コード

#include <bits/stdc++.h>

#define N 200010 

using namespace std;

int head[N], to[N << 1], nxt[N << 1], tot;

char *p1, *p2, buf[100000];

#define nc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1 ++ )

int rd() {
	int x = 0, f = 1;
	char c = nc();
	while (c < 48) {
		if (c == '-')
			f = -1;
		c = nc();
	}
	while (c > 47) {
		x = (((x << 2) + x) << 1) + (c ^ 48), c = nc();
	}
	return x * f;
}

inline void add(int x, int y) {
	to[ ++ tot] = y;
	nxt[tot] = head[x];
	head[x] = tot;
}

int d[N], x[N], y[N];

int main() {
	int n = rd(), k = rd();
	for (int i = 2; i <= n; i ++ ) {
		x[i] = rd(), y[i] = rd();
		d[x[i]] ++ ;
		d[y[i]] ++ ;
	}

	int mx = 0;
	for (int i = 2; i <= n; i ++ ) {
		int s1 = d[x[i]], s2 = d[y[i]];
		if (s1 < s2)
			swap(s1, s2);
		if (s1 >= 3) {
			if (s2 >= 3) {
				mx = max(mx, 2);
			}
			else if(s2 <= 2) {
				mx = max(mx, 1);
			}
		}
	}

	int sum = 0;
	for (int i = 1; i <= n; i ++ ) {
		if (d[i] == 1) {
			sum ++ ;
		}
	}

	mx *= k;

	cout << sum - mx << endl ;
	return 0;
}

小结:有意思的题~

おすすめ

転載: www.cnblogs.com/ShuraK/p/11256684.html