第二种方法就是直接将所有的已知的状态都作为一个节点放置到图当中,同时建立相应的边,然后其他的做法与方法一相似,还是建立源点和终点,然后再求解最大流,输出最终的结果,具体实现见如下代码:
#include<iostream>
#include<vector>
#include<string>
#include<set>
#include<stack>
#include<queue>
#include<map>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<sstream>
#include<cstdio>
#include<deque>
#include<functional>
using namespace std;
const int Inf = 1 << 30;
class Edge{
public:
int from, to, cap, flow;
};
class Solve{
public:
int n, m, k;
vector<Edge> edge;
vector<int> G[405];
vector<string> name;
int source[405], target[405];
int amount;
int getID(string temp){
for (int i = 0; i < name.size(); i++){
if (name[i] == temp) return i;
}
name.push_back(temp);
return name.size() - 1;
}
void addEdge(int from,int to,int cap){
Edge temp;
temp.from = from, temp.to = to, temp.cap = cap, temp.flow = 0;
edge.push_back(temp);
Edge temp2;
temp2.from = to, temp2.to = from, temp.cap = 0, temp.flow = 0;
edge.push_back(temp2);
int total = edge.size();
G[from].push_back(total-2);
G[to].push_back(total - 1);
}
int MaxFlow(int start,int end){
int flow = 0;
int d[405];
while (true){
memset(d, 0, sizeof(d));
d[start] = Inf;
int parent[405];
queue<int> q;
q.push(start);
while (!q.empty()){
int id = q.front();
q.pop();
for (int i = 0; i < G[id].size(); i++){
int ide = G[id][i];
int to = edge[ide].to;
if (!d[to]&&edge[ide].cap > edge[ide].flow){
d[to] = min(d[id],edge[ide].cap-edge[ide].flow);
parent[to] = ide;
q.push(to);
}
}
if (d[end]) break;
}
if (!d[end]) break;
flow += d[end];
for (int i = end; i != start; i = edge[parent[i]].from){
edge[parent[i]].flow += d[end];
edge[parent[i] ^ 1].flow -= d[end];
}
}
return flow;
}
void Init(){
edge.clear();
name.clear();
for (int i = 0; i < 405; i++) G[i].clear();
cin >> n;//插座 目标
for (int i = 0; i < n; i++){
string temp;
cin >> temp;
int id = getID(temp);
target[i] = id;
}
cin >> m;//设备 源头
for (int i = 0; i < m; i++){
string tempp,temp;
cin >> tempp>>temp;
int id = getID(temp);
source[i] = id;
}
cin >> k;//转换器
for (int i = 0; i < k; i++){
string temp1, temp2;
cin >> temp1 >> temp2;
int id1, id2;
id1 = getID(temp1);
id2 = getID(temp2);
addEdge(id1, id2, Inf);
}
int ind = name.size();//起始点
for (int i = 0; i < m; i++){
int id = source[i];
addEdge(ind, id, 1);
}
ind = ind + 1;
for (int i = 0; i < n; i++){
int id = target[i];
addEdge(id, ind, 1);
}
amount = name.size();
}
void Deal(){
Init();
int ans = MaxFlow(amount, amount + 1);
cout << m - ans << endl;
}
};
int main(){
Solve a;
int Case;
cin >> Case;
while (Case--){
a.Deal();
if (Case) cout << endl;
}
system("pause");
return 0;
}
/*
6
4
A
B
C
D
5
laptop B
phone C
pager B
clock B
comb X
3
B X
X A
X D
*/