谜一样的题意的题目,我真的是!@#¥%……&*(。
题意就是说,我有n个插头,m个电器,k个转换器和插头之间的组合(类似于交换机?),比如样例中的B X,就说明B可以把接受到的全部流量转移到X中,然后X A,说明X中的全部流量可以转移到A上。但是,我们只有n个插头,只有插头才可以接电源充电。m个电器也有相对应能用的插头,比如样例的phone是不能用B插头的,只能用C。
然后,套用一下网络流EK模版,搞定。下面的数组至少要开300 * 300的貌似,200会RE,估计他的k个数据里面又偷偷引入了一堆新的插头或者转换器什么的。
#include<iostream>
#include<queue>
#include<cstring>
#include<map>
#include<cstdio>
using namespace std;
const int maxn = 305;
const int INF = 0x7fffffff;
int r[maxn][maxn];
bool visit[maxn];
int pre[maxn];
int cnt = 1;
bool bfs(int s, int t)
{
int p;
queue <int> q;
memset(pre, -1, sizeof(pre));
memset(visit, false, sizeof(visit));
pre[s] = s;
visit[s] = true;
q.push(s);
while(!q.empty())
{
p = q.front();
q.pop();
for(int i = 0; i <= cnt; i++)
{
if(r[p][i] > 0 && !visit[i])
{
pre[i] = p;
visit[i] = true;
if(i == t)
return true;
q.push(i);
}
}
}
return false;
}
int EdmondsKarp(int s,int e)
{
int flow = 0, d, i;
while(bfs(s, e))
{
d = INF;
for(i = e; i != s; i = pre[i])
d = d < r[pre[i]][i] ? d : r[pre[i]][i];
for(i = e; i != s; i = pre[i])
{
r[pre[i]][i] -= d;
r[i][pre[i]] += d;
}
flow += d;
}
return flow;
}
int main()
{
int u, v, w;
int m, n, k;
map <string, int> devices, receptacles, adapters;
map <string, int>::iterator iter;
char str1[30], str2[30];
memset(r, 0, sizeof(r));
scanf("%d", &n);
for(int i = 0; i < n; i++)
{
scanf("%s", str1);
receptacles[str1] = cnt++;
}
scanf("%d", &m);
for(int i = 0; i < m; i++)
{
scanf("%s%s", &str1, &str2);
if(devices.find(str1) == devices.end())
{
u = cnt;
devices[str1] = cnt++;
}
else
u = devices[str1];
if(receptacles.find(str2) == receptacles.end())
{
v = cnt;
adapters[str2] = cnt++;
}
else
v = receptacles[str2];
r[u][v] = 1;
}
scanf("%d", &k);
for(int i = 0; i < k; i++)
{
scanf("%s%s", &str1, &str2);
if(receptacles.find(str1) != receptacles.end())
u = receptacles[str1];
else
u = adapters[str1];
if(receptacles.find(str2) != receptacles.end())
v = receptacles[str2];
else
v = adapters[str2];
r[u][v] = INF;
}
for(iter = devices.begin(); iter != devices.end(); iter++)
r[0][iter->second] = 1;
for(iter = receptacles.begin(); iter != receptacles.end(); iter++)
r[iter->second][cnt] = 1;
printf("%d\n", m - EdmondsKarp(0, cnt));
return 0;
}