有 N 張選票,每票要么「喜歡貓 X,討厭狗 Y」,要么「喜歡狗 X,討厭貓 Y」。選出一組貓和狗,使滿足的選票數最大。若一票的喜歡對象被選中且討厭對象未被選中,則該票滿足。
V - matching。#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
const int MAXV = 510;
struct Vote { char like[5], dislike[5]; } cat[MAXV], dog[MAXV];
vector<int> G[MAXV];
int link[MAXV], catCnt, dogCnt, V;
bool vis[MAXV];
bool dfs(int u) {
for (int v : G[u]) if (!vis[v]) {
vis[v] = true;
if (link[v] == -1 || dfs(link[v])) {
link[v] = u;
return true;
}
}
return false;
}
int main() {
int T; scanf("%d", &T);
while (T--) {
int c, d; scanf("%d%d%d", &c, &d, &V);
catCnt = dogCnt = 0;
char like[5], hate[5];
for (int i = 0; i < V; ++i) {
scanf("%s%s", like, hate);
if (like[0] == 'C') {
strcpy(cat[catCnt].like, like);
strcpy(cat[catCnt].dislike, hate);
G[catCnt++].clear();
} else {
strcpy(dog[dogCnt].like, like);
strcpy(dog[dogCnt].dislike, hate);
++dogCnt;
}
}
for (int i = 0; i < catCnt; ++i)
for (int j = 0; j < dogCnt; ++j)
if (!strcmp(cat[i].like, dog[j].dislike) ||
!strcmp(cat[i].dislike, dog[j].like))
G[i].push_back(j);
memset(link, -1, sizeof(link));
int match = 0;
for (int i = 0; i < catCnt; ++i) {
memset(vis, 0, sizeof(vis));
if (dfs(i)) ++match;
}
printf("%d\n", V - match);
}
return 0;
}
O(C·D·L),L 為字符串長度(≤4)。O(V·E),V ≤ 500,E ≤ C·D,極快。