题目的意思就是有n种插口,然后有m个设备,每个设备可以插一种插口,然后有k种(注意是种,个数不限)转换器,可以把一种设备的插口转成另一种.
现在问有几个设备充不上电.,
首先用一个超级源点 把插口都连到超级源点,容量为1.
然后把所有设备都连到超级汇点.
然后通过转化器构造中间的边,容量是INF.
在ek模板算法就能算出最大流..
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
const int N = 500;
const int INF = 0x3f3f3f3f;
int cap[N][N];
int flow[N][N];
char str[N][25];
char temp[25];
char temp2[25];
int p[N];
int a[N];
int sum;
int num;
int n,m,k,f;
int search(char *c) {
for (int i = 1 ; i < sum ;i++) {
if(strcmp(c , str[i]) == 0)
return i;
}
strcpy(str[sum] , c);
return sum++;
}
int ek(int t) {
queue<int> q;
memset(flow , 0 ,sizeof(flow));
f = 0;
while(1) {
memset(a, 0 ,sizeof(a));
a[0] = INF;
q.push(0);
while(!q.empty()) {
int u = q.front() ;
q.pop();
for (int v = 0 ; v <= t; v++) {
if (!a[v] && cap[u][v] - flow[u][v] > 0) {
p[v] = u ;
q.push(v);
a[v] = a[u] < cap[u][v] - flow[u][v] ? a[u] : cap[u][v] - flow[u][v];
}
}
}
if (a[t] == 0)
break;
for (int u = t ; u != 0 ;u = p[u]) {
flow[p[u]][u] += a[t];
flow[u][p[u]] -= a[t];
}
f += a[t];
}
return m - f;
}
int main () {
int t;
scanf("%d",&t);
while(t--) {
sum = 1;
memset(cap , 0 ,sizeof(cap));
scanf("%d",&n);
for (int i = 1 ; i <= n ;i++) {
scanf("%s",temp);
cap[0][search(temp)] += 1;
}
scanf("%d",&m);
for (int i = 1 ; i <= m ;i++) {
scanf("%s",temp);
scanf("%s",temp);
p[i] = search(temp);
}
scanf("%d",&k);
for (int i = 0 ; i < k ;i++) {
scanf("%s",temp);
scanf("%s",temp2);
int u = search(temp);
int v = search(temp2);
cap[v][u] = INF;
}
for (int i = 1 ; i <= m ;i++) {
cap[p[i]][sum] += 1;
}
int res = ek(sum);
printf("%d\n",res);
if(t)
printf("\n");
}
}