很显然 插头与插座之间的关系符合二分图
所以老样子,先建图,后匈牙利
因为有插头转接器
所以这题的建图需要先计算出来某个插头可以到的所有插座
然后在进行建图
#include<iostream>
#include<cstring>
#include<algorithm>
#include<math.h>
#include<vector>
#include<set>
#include<queue>
#include<list>
#include<map>
using namespace std;
const int maxi = 110;
int mp[maxi][maxi], used[maxi], who[maxi];
map<string, vector<string> > drec;
map<string, vector<string> > oriDrec;
map<string, int> rece_to_id;
map<string, string> device_to_plug;
map<string, int> device_to_index;
string device[maxi];
string rece[maxi];
int n, m;
void inti() {
memset(mp, 0, sizeof(mp));
memset(used, 0, sizeof(used));
memset(who, 0, sizeof(who));
drec.clear();
oriDrec.clear();
rece_to_id.clear();
device_to_index.clear();
device_to_plug.clear();
}
void trackback(string ori) {
vector<string> v = drec[ori];
set<string> add;
for (int i = 0; i < v.size(); i++) {
if (drec.find(v[i]) != drec.end()) {
vector<string> t = drec[v[i]];
for (int j = 0; j < t.size(); j++) {
if (find(v.begin(), v.end(), t[j]) == v.end()) {//若是原先v中没有的方向,则将其加入
add.insert(t[j]);
}
}
}
}
if (add.size() != 0) {
for (set<string>::iterator it = add.begin(); it != add.end(); it++) {
v.push_back(*it);
}
drec[ori] = v;
vector<string> par = oriDrec[ori];
for (int i = 0; i < par.size(); i++) {
trackback(par[i]);
}
}
}
void getDre() {
map<string, vector<string>>::iterator it;
for (it = drec.begin(); it != drec.end(); it++) {
trackback(it->first);
}
}
void read() {
cin >> n;
string str, plug;
for (int i = 1; i <= n; i++) {
cin >> str;
rece[i] = str;
rece_to_id[str] = i;
}
cin >> m;
for (int i = 1; i <= m; i++) {
cin >> str >> plug;
device_to_plug[str] = plug;
device_to_index[str] = i;
device[i] = str;
}
int t;
cin >> t;
string from, to;
for (int i = 0; i < t; i++) {
cin >> from >> to;
vector<string> tos = drec[from];
tos.push_back(to);
drec[from] = tos;
vector<string> froms = oriDrec[to];
froms.push_back(from);
oriDrec[to] = froms;
}
for (map<string, vector<string>>::iterator it = drec.begin(); it != drec.end(); it++) {
vector<string> t = it->second;
t.push_back(it->first);
it->second = t;
}
}
void build() {
for (int i = 1; i <= m; i++) {
string str = device[i];
string plug = device_to_plug[str];
if(rece_to_id.find(plug)!=rece_to_id.end()){
mp[i][rece_to_id[plug]]=1;
}
vector<string> plug_to = drec[plug];
for (int j = 0; j < plug_to.size(); j++) {
if (rece_to_id.find(plug_to[j]) != rece_to_id.end()) {
mp[i][rece_to_id[plug_to[j]]] = 1;
}
}
}
}
int dfs(int u) {
for (int i = 1; i <= n; i++) {
if (mp[u][i] && !used[i]) {
used[i] = 1;
if (!who[i] || dfs(who[i])) {
who[i] = u;
return 1;
}
}
}
return 0;
}
int hungry() {
int all = 0;
for (int i = 1; i <= m; i++) {
memset(used, 0, sizeof(used));
if (dfs(i))all++;
}
return all;
}
void solve() {
// for(int i=1;i<=m;i++){
// cout << "name:"<<device[i]<<" ";
// for(int j=1;j<=n;j++){
// if(mp[i][j])cout << rece[j]<<" ";
// }
// cout << endl;
// }
int mat = hungry();
// cout << mat << endl;
cout << m - mat << endl;
}
int main() {
int t;
cin >> t;
while (t--) {
inti();
read();
getDre();
build();
solve();
if(t) cout << endl;
}
}