题意:读题很恶心···。大概就是说现在有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; }