マッチング。
- const int TOP = 100 + 5;
- const int BOT = 100 + 5;
- const int N = TOP + BOT + 5;
- vector<int> g[N];
- int match[N];
- bool vis[N];
- bool rec(int curr)
- {
- vis[curr] = true;
- for (int i = 0; i < g[curr].size(); ++i) {
- int next = g[curr][i];
- int w = match[next];
- if (w < 0 || (!vis[w] && rec(w))) {
- match[curr] = next;
- match[next] = curr;
- return true;
- }
- }
- return false;
- }
- int matching(int n)
- {
- int f = 0;
- fill(match, match + N, -1);
- for (int i = 0; i < n; ++i) {
- if (match[i] < 0) {
- fill(vis, vis + N, false);
- f += rec(i);
- }
- }
- return f;
- }
- class PointyWizardHats {
- public:
- int getNumHats(vector <int> tH,
- vector <int> tR,
- vector <int> bH,
- vector <int> bR)
- {
- fill(g, g + N, vector<int>());
- fill(vis, vis + N, false);
- const int T = tH.size();
- const int B = bH.size();
- const double eps = 1e-8;
- for (int i = 0; i < T; ++i) {
- for (int j = 0; j < B; ++j) {
- double tA = (double)tR[i] / sqrt(tR[i] * tR[i] + tH[i] * tH[i]);
- double bA = (double)bR[j] / sqrt(bR[j] * bR[j] + bH[j] * bH[j]);
- if (tA + eps < bA && tR[i] < bR[j]) {
- int a = i;
- int b = j + TOP;
- g[a].push_back(b);
- g[b].push_back(a);
- }
- }
- }
- return matching(T);
- }
- };