题目链接:poj 1087
这道题,感觉考得是阅读理解啊,题目又臭又长。。。。
参考题意:https://blog.csdn.net/qq_38367681/article/details/81392291
题意:在一个会议室里有n种插座,每种插座一个,每个插座只能插一种以及一个电器(或者适配器),有m个电器,每个电器有一个插头需要插在相应一种插座上,不是所有电器都能在会议室找到相应插座,有k种适配器,每种适配器可以有无限多数量,每种适配器(a, b)可以把b类插座变为a类插座,问最后有多少个电器无法使用。
题解:参考链接:https://www.cnblogs.com/kuangbin/archive/2012/08/21/2649946.html
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<map>
#include<string>
#include<iostream>
using namespace std;
#define INF 0x3f3f3f3f
const int maxn=500;
int capacity[maxn][maxn]; ///存储值
int flow[maxn];
int path[maxn],start,end;
int n; ///建模后的总结点
queue<int> myqueue;
int bfs()
{
while(!myqueue.empty()) myqueue.pop();
memset(path,-1,sizeof(path));
path[start]=0;
flow[start]=INF;
myqueue.push(0);
while(!myqueue.empty())
{
int t=myqueue.front();
myqueue.pop();
if(t==end) break;
for(int i=0;i<=n;i++)
{
if(i!=start&&path[i]==-1&&capacity[t][i])
{
flow[i]=min(flow[t],capacity[t][i]);
myqueue.push(i);
path[i]=t;
}
}
}
if( path[end]==-1 ) return -1;
return flow[end];
}
int Edmond_Karp()
{
int max_flow=0;
int step,now,pre;
while((step=bfs())!=-1)
{
now=end;
max_flow+=step;
while(now!=start){
pre=path[now];
capacity[pre][now]-=step;
capacity[now][pre]+=step;
now=pre;
}
}
return max_flow;
}
map<string,int> hash;
int main()
{
cin.tie(0);
ios::sync_with_stdio(0);
string str1,str2;
int N,M,K;
while(~scanf("%d",&N))
{
hash.clear();
memset(capacity,0,sizeof(capacity));
start=0; ///源点
end=1; ///汇点
int tol=2;
while(N--)
{
cin>>str1;
hash[str1]=tol;
capacity[0][tol]=1; ///建立源点与插座之间的边
tol++;
}
scanf("%d",&M);
for(int i=1;i<=M;i++)
{
cin>>str1>>str2;
if(hash[str1]==0) hash[str1]=tol++;
if(hash[str2]==0) hash[str2]=tol++;
capacity[hash[str1]][end]=1; ///建立用电器与汇点的边
capacity[hash[str2]][hash[str1]]=1; ///建立插座(或者适配器)与用电器之间的边
}
scanf("%d",&K);
while(K--)
{
cin>>str1>>str2;
if(hash[str1]==0) hash[str1]=tol++;
if(hash[str2]==0) hash[str2]=tol++;
capacity[hash[str2]][hash[str1]]=INF; ///题目say了,适配器是无穷无尽的,故把插座与适配器设为INF
}
n=tol-1; ///总节点
printf("%d\n",M-Edmond_Karp());
}
return 0;
}