题意:
给你n种插座和m种电器,但是发现电器和插座有些不匹配,现给你每个电器需要的插座种类。然后和插座转换器的类型
求最少有多少个电器没有插座
最大流问题
关键问题在于建图
题目中给的都是字母,需要转化为相应的数字,然后再建图
每中电器都相应的转化为数字,这时候用的就是map的一一对应了
然后建图:
源点----->插座(转换器用来插座对插座)---->电器---->汇点
插座----->插座的流量要设置为无限大
因为转换器是无限多的,所以插座----->插座是无限大的
其他的流量都为1,防止一个电器连多个插座
图建好,题目也差不多了!!
#include<stdio.h>
#include<iostream>
#include<queue>
#include<map>
#include<algorithm>
#include<string.h>
using namespace std;
const int maxn=2000;
const int inf=0x3f3f3f3f;
int flow[maxn][maxn];
int R1[maxn];
int R2[maxn];
int R3[maxn][3];
int n1,n2,n3;
map<string,int>Map;
int EK(int s,int t)
{
queue<int>q;
int f=0;
int a[maxn],p[maxn];
while(1)
{
memset(a,0,sizeof(a));
a[s]=0x3f3f3f3f;
q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=0; i<=n1+n2+1; i++)
{
if(!a[i]&&flow[u][i])
{
p[i]=u;
q.push(i);
a[i]=min(a[u],flow[u][i]);
if(i==t)
break;
}
}
}
if(a[t]==0)
break;
for(int i=t; i!=s; i=p[i])
{
flow[p[i]][i]-=a[t];
flow[i][p[i]]+=a[t];
}
f+=a[t];
}
return f;
}
int main()
{
Map.clear();
memset(flow,0,sizeof(flow));
cin>>n1;
int n12=n1;
string str,scr;
int T=0;
for(int i=1; i<=n1; i++)
{
cin>>str;
Map[str]=i;
}
cin>>n2;
for(int i=1; i<=n2; i++)
{
cin>>str>>scr;
int k;
if(Map[scr]==0)//如果出现新的规格的插座
{
k=Map[scr]=++n1;
}
else
{
k=Map[scr];
}
R2[i]=k;//储存第i个物品对应插座K
}
cin>>n3;
for(int i=1; i<=n3; i++)
{
cin>>str>>scr;//将转换器通过Map转换为数字存入R3
if(Map[str]==0)
{
Map[str]=++n1;
}
R3[i][1]=Map[str];
if(Map[scr]==0)
{
Map[scr]=++n1;
}
R3[i][2]=Map[scr];
}//转换完毕,开始建图
for(int i=1; i<=n12; i++) //源点对插座
{
flow[0][i]=1;
}
for(int i=1; i<=n12; i++) //插座对电器
{
for(int j=1; j<=n2; j++)
{
if(R2[j]==i)
flow[i][j+n1]=1;
}
}
for(int i=n12+1; i<=n1; i++) //新出现的插座对电器
{
for(int j=1; j<=n2; j++)
{
if(R2[j]==i)
flow[i][j+n1]=1;
}
}
for(int i=1; i<=n3; i++) //转换器之间的插座相对
{
flow[R3[i][2]][R3[i][1]]=inf;
}
for(int i=1; i<=n2; i++) //电器对汇点
{
flow[i+n1][n1+n2+1]=1;
}
// for(int i=0;i<=n1+n2+1;i++)
// {
// for(int j=0;j<=n1+n2+1;j++)
// {
// printf("%d ",flow[i][j]);
// }
// printf("\n");
// }
printf("%d\n",n2-EK(0,n1+n2+1));
}