1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
| // 더 많은 정보는 42jerrykim.github.io 에서 확인하세요.
#include <bits/stdc++.h>
using namespace std;
struct Vote {
bool keepCat; // true if keep cat, false if keep dog
int catIndex; // cat index involved (keep if keepCat, remove if !keepCat)
int dogIndex; // dog index involved (remove if keepCat, keep if !keepCat)
};
struct HopcroftKarp {
int leftSize, rightSize;
vector<vector<int>> adj; // adj[u] = list of v on right
vector<int> dist; // distance for BFS layering (left side)
vector<int> pairU, pairV; // matches: left->right, right->left
HopcroftKarp(int L, int R) : leftSize(L), rightSize(R) {
adj.assign(L, {});
pairU.assign(L, -1);
pairV.assign(R, -1);
dist.resize(L);
}
void addEdge(int u, int v) { // u in [0,L), v in [0,R)
adj[u].push_back(v);
}
bool bfs() {
queue<int> q;
const int INF = 1e9;
bool foundFreeOnRight = false;
for (int u = 0; u < leftSize; ++u) {
if (pairU[u] == -1) {
dist[u] = 0;
q.push(u);
} else {
dist[u] = INF;
}
}
while (!q.empty()) {
int u = q.front(); q.pop();
for (int v : adj[u]) {
int u2 = pairV[v];
if (u2 == -1) {
foundFreeOnRight = true;
} else if (dist[u2] == INF) {
dist[u2] = dist[u] + 1;
q.push(u2);
}
}
}
return foundFreeOnRight;
}
bool dfs(int u) {
for (int v : adj[u]) {
int u2 = pairV[v];
if (u2 == -1 || (dist[u2] == dist[u] + 1 && dfs(u2))) {
pairU[u] = v;
pairV[v] = u;
return true;
}
}
dist[u] = INT_MAX;
return false;
}
int maxMatching() {
int matching = 0;
while (bfs()) {
for (int u = 0; u < leftSize; ++u) {
if (pairU[u] == -1 && dfs(u)) {
++matching;
}
}
}
return matching;
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
if (!(cin >> T)) return 0;
while (T--) {
int c, d, v;
cin >> c >> d >> v;
vector<Vote> catLovers; // CxD
vector<Vote> dogLovers; // DxC
catLovers.reserve(v);
dogLovers.reserve(v);
for (int i = 0; i < v; ++i) {
string s1, s2;
cin >> s1 >> s2; // e.g., "C1" "D2"
char k1 = s1[0], k2 = s2[0];
int n1 = stoi(s1.substr(1));
int n2 = stoi(s2.substr(1));
if (k1 == 'C' && k2 == 'D') {
// keep cat n1, remove dog n2
catLovers.push_back({true, n1, n2});
} else {
// k1 == 'D' && k2 == 'C'
// keep dog n1, remove cat n2
dogLovers.push_back({false, n2, n1});
}
}
int L = (int)catLovers.size();
int R = (int)dogLovers.size();
HopcroftKarp hk(L, R);
// Conflict edges
for (int i = 0; i < L; ++i) {
for (int j = 0; j < R; ++j) {
if (catLovers[i].catIndex == dogLovers[j].catIndex ||
catLovers[i].dogIndex == dogLovers[j].dogIndex) {
hk.addEdge(i, j);
}
}
}
int maxMatch = hk.maxMatching();
cout << (v - maxMatch) << '\n';
}
return 0;
}
|