結果
問題 | No.763 Noelちゃんと木遊び |
ユーザー | drken1215 |
提出日時 | 2018-02-22 14:26:49 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 2,806 bytes |
コンパイル時間 | 755 ms |
コンパイル使用メモリ | 77,168 KB |
実行使用メモリ | 22,084 KB |
最終ジャッジ日時 | 2024-11-06 19:45:17 |
合計ジャッジ時間 | 3,841 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | WA | - |
testcase_01 | WA | - |
testcase_02 | WA | - |
testcase_03 | WA | - |
testcase_04 | WA | - |
testcase_05 | WA | - |
testcase_06 | WA | - |
testcase_07 | WA | - |
testcase_08 | WA | - |
testcase_09 | WA | - |
testcase_10 | WA | - |
testcase_11 | WA | - |
testcase_12 | WA | - |
testcase_13 | WA | - |
testcase_14 | WA | - |
testcase_15 | WA | - |
testcase_16 | WA | - |
testcase_17 | WA | - |
testcase_18 | WA | - |
testcase_19 | WA | - |
testcase_20 | WA | - |
ソースコード
#include <iostream> #include <vector> #include <queue> #include <cstring> using namespace std; const int MAX = 110000; int N; vector<int> tree[MAX]; /* Hopcroft-Karp の二部マッチング */ const int MAX_L = MAX; const int MAX_R = MAX; struct Graph { vector<int> adj[MAX_L]; Graph() {} inline vector<int>& operator [] (int i) { return adj[i]; } void addedge(int from, int to) { adj[from].push_back(to); } friend ostream& operator << (ostream& s, const Graph& G) { s << endl; for (int i = 0; i < MAX_L; ++i) { if (G.adj[i].empty()) continue; s << i << " : "; for (int j = 0; j < G.adj[i].size(); ++j) { s << G.adj[i][j] << ", "; } } return s; } }; Graph G; static int L = 0; // ここに左ノードの使いたい頂点数をセット static bool seen[MAX_L]; static bool matched[MAX_L]; static int level[MAX_L]; static int matching[MAX_R]; void hobfs(Graph &G) { queue<int> que; for (int left = 0; left < L; ++left) { level[left] = -1; if (!matched[left]) { que.push(left); level[left] = 0; } } level[L] = L; while (!que.empty()) { int left = que.front(); que.pop(); for (int i = 0; i < G[left].size(); ++i) { int right = G[left][i]; int next = matching[right]; if (level[next] == -1) { level[next] = level[left] + 1; que.push(next); } } } } bool hodfs(Graph &G, int left) { if (left == L) return true; if (seen[left]) return false; seen[left] = true; for (int i = 0; i < G[left].size(); ++i) { int right = G[left][i]; int next = matching[right]; if (level[next] > level[left] && hodfs(G, next)) { matching[right] = left; return true; } } return false; } int Hopcroft_Karp(Graph &G) { for (int i = 0; i < MAX_R; ++i) matching[i] = L; memset(matched, 0, sizeof(matched)); int res = 0; while (true) { hobfs(G); memset(seen, 0, sizeof(seen)); bool finished = true; for (int left = 0; left < L; ++left) { if (!matched[left] && hodfs(G, left)) { matched[left] = true; ++res; finished = false; } } if (finished) break; } return res; } /* ツリーを二部グラフに */ void rec(int v, int flag, int p = -1) { if (flag == 0) ++L; if (p != -1) { if (flag == 0) { G.addedge(v, p); } else { G.addedge(p, v); } } for (auto ch : tree[v]) { if (ch == p) continue; rec(ch, 1 - flag, v); } } int main() { cin >> N; for (int i = 0; i < N-1; ++i) { int u, v; cin >> u >> v; --u, --v; tree[u].push_back(v); tree[v].push_back(u); } /* ツリーは二部グラフなので「左」と「右」にわける */ rec(0, 0); /* 最大マッチングを求める */ int max_matching = Hopcroft_Karp(G); /* N - 最大マッチング */ cout << N - max_matching << endl; }