//网络流——通过构图用最大流来作做大匹配 //将用电器(device)与源点相连 //插座(plug)和汇点相连 //适配器与插座相连,且权值为INF //将最大匹配问题构图转化为最大流问题,再用汇点总流减去最大流得到答案 #include<iostream> #include<queue> #include<map> #include<cstring> #include<string> #define INF 2000000000 using namespace std; int flow[505][505],cap[505][505]; int rflow[505],pre[505]; int u,v,c,maxflow,st,ed,n,m,k; int node; int main() { //freopen("in.txt","r",stdin); maxflow = 0; node = 1;//结点编号,将不同的适配器,用电器和插头都相应给上编号 st = 0; ed = 1; string plug,device,adapter; map<string,int> M;//用map实现对不同种类用电器,适配器等的结点编号关联 cin >> n; memset(flow,0,sizeof(flow)); memset(cap,0,sizeof(cap)); for(int i = 0;i < n;++i) { cin >> plug; M[plug] = ++node; cap[node][ed] = 1; } cin >> m; for(int i = 0;i < m;++i) { cin >> device >> plug; M[device] = ++node; cap[st][M[device]] = 1; if(!M.count(plug)) { M[plug] = ++node; } cap[M[device]][M[plug]] = 1; } cin >> k; for(int i = 0;i < k;++i) { cin >> adapter >> plug; if(!M.count(adapter)) { M[adapter] = ++node; } if(!M.count(plug)) { M[plug] = ++node; } cap[M[adapter]][M[plug]] = INF;//此题要注意的是,他又说适配器的数量是无限个,因此构造适配器到插头的权值应为INF } for(;;)//最大流模板 { queue<int> q; memset(rflow,0,sizeof(rflow)); rflow[st] = INF; q.push(st); while(!q.empty()) { u = q.front(); q.pop(); for(v = 0;v <= node;++v) { if(!rflow[v] && cap[u][v] > flow[u][v]) { rflow[v] = min(rflow[u],cap[u][v] - flow[u][v]); pre[v] = u; q.push(v); } } } if(rflow[ed] == 0) break; for(u = ed;u != st;u = pre[u]) { flow[pre[u]][u] += rflow[ed];//更新正向流量 flow[u][pre[u]] -= rflow[ed];//更新反向流量 } maxflow += rflow[ed]; } printf("%d/n",m - maxflow);//到汇点的流量之和减去最大流则为答案 return 0; }