题意:读题很恶心···。大概就是说现在有n个不同的插孔,m台不同的用电器,k种适配器。(适配器就相当于一个中间插座,比如一个适配器是(x,y)。有一台用电器必须插x插孔,但是现在只有一个y插孔,那么就可以通过适配器来连接)。另外需要注意的就是给出的是适配器的种数,每一种的数量无限制。
题解:建图的大概思路。s-->电器-->适配器-->插孔-->t
#include <queue>
#include <cstring>
#include <iostream>
using namespace std;
#define N 101
#define INF 9999
char recep[N][25];
char device[N][25];
struct Item
{
char in[25];
char out[25];
} adapt[N];
bool vis[N*3];
int pre[N*3];
int cap[N*3][N*3];
int flow[N*3][N*3];
int n, m, k;
int s, t, res;
void build_map()
{
s = 0;
t = n + m + k + 1;
memset(cap,0,sizeof(cap));
int i, j;
for ( i = 1; i <= m; i++ )
{
cap[s][i] = 1; // s到电器
for ( j = 1; j <= n; j++ ) //电器到插孔
if ( ! strcmp(device[i],recep[j]) )
cap[i][j+m+k] = 1;
for ( j = 1; j <= k; j++ ) //电器到适配器
if ( ! strcmp(device[i],adapt[j].in) )
cap[i][j+m] = 1;
}
for ( i = 1; i <= k; i++ )
{
for ( j = 1; j <= k; j++ ) // 适配器之间联系
if ( i != j && !strcmp(adapt[i].out, adapt[j].in) )
cap[i+m][j+m] = INF; // 数量不限制,所以是INF
for ( j = 1; j <= n; j++ ) // 适配器到插孔
if ( ! strcmp(adapt[i].out, recep[j]) )
cap[i+m][j+m+k] = 1;
}
for ( i = 1; i <= n; i++ ) //插孔到t
cap[i+m+k][t] = 1;
}
bool find_path () // BFS找增广路
{
memset(pre,-1,sizeof(-1));
memset(vis,0,sizeof(vis));
queue<int> que;
vis[s] = 1;
que.push(s);
while ( ! que.empty () )
{
int u = que.front ();
que.pop ();
for ( int v = t; v >= s; v-- )
{
if ( ! vis[v] && cap[u][v] > flow[u][v] )
{
vis[v] = 1;
pre[v] = u;
if ( v == t ) return true;
que.push(v);
}
}
}
return false;
}
int max_flow()
{
res = 0;
memset(flow,0,sizeof(flow));
while ( 1 )
{
if ( ! find_path() ) break;
int tt = t;
int minFlow = INF;
while ( pre[tt] != -1 )
{
if ( minFlow > cap[pre[tt]][tt] - flow[pre[tt]][tt] )
minFlow = cap[pre[tt]][tt] - flow[pre[tt]][tt];
tt = pre[tt];
}
tt = t;
while ( pre[tt] != -1 )
{
flow[pre[tt]][tt] += minFlow;
flow[tt][pre[tt]] -= minFlow;
tt = pre[tt];
}
res += minFlow;
}
return res;
}
int main()
{
int i;
char name[25];
scanf("%d",&n);
for ( i = 1; i <= n; i++ )
scanf("%s",recep[i]);
scanf("%d",&m);
for ( i = 1; i <= m; i++ )
scanf("%s %s", name, device[i]);
scanf("%d",&k);
for ( i = 1; i <= k; i++ )
scanf("%s %s",adapt[i].in, adapt[i].out);
build_map();
printf("%d\n", m - max_flow());
return 0;
}