说实话,这几道匹配问题真是抽象理发机
这题用的匈牙利求最大匹配
#include<iostream>
#include<cstring>
#include<algorithm>
#include<math.h>
#include<vector>
#include<set>
#include<queue>
#include<list>
#include<map>
using namespace std;
int n;
int mp[27][27], used[27], who[27], save[27], ans[27];
string big[70], small[70];
int dre[5];
map<char, char> dic;
void init() {
memset(used, 0, sizeof(used));
memset(mp, 1, sizeof(mp));
for (int i = 0; i < 70; i++) {
big[i] = "";
small[i] = "";
}
memset(save, -1, sizeof(save));
memset(ans, -1, sizeof(ans));
dic.clear();
memset(dre, -1, sizeof(dre));
}
void read() {
for (int i = 0; i < n; i++) {
cin >> big[i];
}
for (int i = 0; i < n; i++) {
cin >> small[i];
}
//建反边
for (int i = 0; i < n; i++) {
string G = big[i];
string g = small[i];
for (int j = 0; j < G.length(); j++) {
for (int k = 0; k < 20; k++) {
if (g.find(char(('a' + k))) == -1) {
mp[(G[j] - 'A')][k] = 0;
}
}
}
}
}
bool dfs(int k) {
for (int i = 0; i < 20; i++) {
if (mp[k][i] && !used[i]) {
used[i] = 1;
if (who[i] == -1 || dfs(who[i])) {
who[i] = k;
return true;
}
used[i] = 0;
}
}
return false;
}
int hungry() {
int all = 0;
memset(who, -1, sizeof(who));
for (int i = 0; i < 20; i++) {
memset(used, 0, sizeof(used));
if (dfs(i))all++;
}
return all;
}
void solve() {
int mat = hungry();
for (int i = 0; i < 20; i++) {
save[i] = who[i];
}
for (int i = 0; i < 20; i++) {
if (save[i] != -1) {
mp[save[i]][i] = 0;
if (mat > hungry()) {
ans[save[i]] = i;
}
mp[save[i]][i] = 1;
}
}
}
int main() {
int coun = 0;
while (cin >> n && n) {
init();
read();
printf("Test #%d:\n", ++coun);
int t = dic.size();
while (true) {
solve();
for (int i = 0; i < 20; i++) {
if (ans[i] != -1) {
dic[char(('A' + i))] = char(('a' + ans[i]));
}
}
if (t == dic.size()) {
break;
} else {
t = dic.size();
}
for (map<char, char>::iterator it = dic.begin(); it != dic.end(); it++) {
char c1 = it->first;
char c2 = it->second;
int num1 = (c1 - 'A') / 5;
int num2 = (c2 - 'a') / 5;
for (int i = num1 * 5; i < num1 * 5 + 5; i++) {
for (int j = 0; j < 20; j++) {
if ((j / 5) != num2) {
mp[i][j] = 0;
}
}
}
}
}
for (int i = 0; i < 20; i++) {
cout << char(('A' + i)) << "-";
if (ans[i] != -1) {
cout << char(('a' + ans[i]));
} else {
cout << "?";
}
if ((i + 1) % 5 == 0) {
cout << endl;
}else{
cout << " ";
}
}
}
}