QOJ.ac

QOJ

ID提交记录ID题目HackerOwner结果提交时间测评时间
#373#181412#7222. The Great Huntckisekiucup-team288Success!2023-09-17 01:42:322023-09-17 01:42:33

详细

Extra Test:

Time Limit Exceeded

input:

10000
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10
10 11
11 12
12 13
13 14
14 15
15 16
16 17
17 18
18 19
19 20
20 21
21 22
22 23
23 24
24 25
25 26
26 27
27 28
28 29
29 30
30 31
31 32
32 33
33 34
34 35
35 36
36 37
37 38
38 39
39 40
40 41
41 42
42 43
43 44
44 45
45 46
46 47
47 48
48 49
49 50
50 51
51 52
52 53...

output:


result:


ID题目提交者结果用时内存语言文件大小提交时间测评时间
#181412#7222. The Great Huntucup-team288#TL 1651ms16860kbC++202.7kb2023-09-16 18:29:122023-09-17 01:43:02

answer

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using i64 = long long;
#define pb emplace_back
#define AI(i) begin(i), end(i)
template<class T> bool chmin(T &a, T b) { return b < a && (a = b, true); }
template<class T> bool chmax(T &a, T b) { return a < b && (a = b, true); }
#ifdef KEV
#define DE(args...) kout("[ " + string(#args) + " ] = ", args)
void kout() { cerr << endl; }
template<class T, class ...U> void kout(T a, U ...b) { cerr << a << ' ', kout(b...); }
template<class T> void debug(T l, T r) { while (l != r) cerr << *l << " \n"[next(l)==r], ++l; }
#else
#define DE(...) 0
#define debug(...) 0
#endif

constexpr int N = 10000;

struct BipartiteMatching {
	int n, m;
	vector<bitset<N>> adj;
	vector<int> l, r, dis, cur;
	BipartiteMatching(int n, int m) : n(n), m(m), adj(n), l(n, -1), r(m, -1), dis(n), cur(n) {}
	void addEdge(int u, int v) { adj[u].set(v); }
	void bfs() {
		vector<int> q;
		for (int i = 0; i < n; i++) {
			if (l[i] == -1) {
				q.push_back(i);
				dis[i] = 0;
			} else {
				dis[i] = -1;
			}
		}
		for (int b = 0; b < int(q.size()); b++) {
			int u = q[b];
			for (int v = adj[u]._Find_first(); v < n; v = adj[u]._Find_next(v)) {
				if (r[v] != -1 && dis[r[v]] == -1) {
					dis[r[v]] = dis[u] + 1;
					q.push_back(r[v]);
				}
			}
		}
	}
	bool dfs(int u) {
		for (int &v = cur[u]; v < n; v = adj[u]._Find_next(v)) {
			if (r[v] == -1 || dis[r[v]] == dis[u] + 1 && dfs(r[v])) {
				l[u] = v, r[v] = u;
				return true;
			}
		}
		return false;
	}
	int maxMatching() {
		int match = 0;
		while (true) {
			for (int i = 0; i < n; i++) {
				cur[i] = adj[i]._Find_first();
			}
			int cnt = 0;
			bfs();
			for (int i = 0; i < n; i++) {
				if (l[i] == -1) {
					cnt += dfs(i);
				}
			}
			if (cnt == 0) {
				break;
			}
			match += cnt;
		}
		return match;
	}
};

int main() {
	cin.tie(nullptr)->sync_with_stdio(false);

	int n;
	cin >> n;

	vector<vector<int>> adj(n);
	for (int i = 0; i < n - 1; i++) {
		int u, v;
		cin >> u >> v;
		u--, v--;
		adj[u].push_back(v);
		adj[v].push_back(u);
	}

	vector<int> dep(n), par(n, -1);
	auto dfs = [&](auto dfs, int u, int p) -> void {
		for (auto v : adj[u]) {
			if (v == p) {
				continue;
			}
			dep[v] = dep[u] + 1;
			par[v] = u;
			dfs(dfs, v, u);
		}
	};
	dfs(dfs, 0, -1);

	BipartiteMatching bm(n, n);

	for (int i = 0; i < n; i++) {
		int u, v;
		cin >> u >> v;
		u--, v--;
		while (u != v) {
			if (dep[u] < dep[v]) {
				swap(u, v);
			}
			bm.addEdge(i, u);
			u = par[u];
		}
		bm.addEdge(i, u);
	}

	if (bm.maxMatching() != n) {
		cout << "No\n";
		return 0;
	}

	cout << "Yes\n";
	
	for (int i = 0; i < n; i++) {
		cout << bm.l[i] + 1 << " \n"[i == n - 1];
	}
}