http://poj.org/problem?id=1087
题目大意:
会议室里有n1个插座,n2个电器,n3种适配器;
一种电器对应一种插座,适配器则可以用于转换;
求最好的情况下有多少电器不能适配。
思路:
1、各个电器各自为一个节点,建立一个源点且源点到电器的容量为1;
2、将室内已有的插座各自为一个节点,建立一个汇点且各个插座到汇点的容量为1;
3、电器节点到插座节点的容量为1;
4、适配器转换的两种插座之间的容量为无穷大;
#pragma warning (disable:4786)
#include<iostream>
#include<string>
#include<map>
using namespace std;
const int inf=1<<30;
const int MAX=601;
int s,t;
int n;
int cap[MAX][MAX];
map <string,int> Map;
int maxflow()
{
int pre[MAX];
int queue[MAX];
int head;
int tail;
int min_flow;
int max_flow=0;
int x,y;
while(true)
{
memset(pre,-1,sizeof(pre));
for(queue[head=tail=0]=s;head<=tail;head++)
{
x=queue[head];
for(int i=1;i<=n;i++)
{
// cout<<"x="<<x<<" i="<<i<<' '<<cap[x][i]<<endl;
if(cap[x][i]>0 && pre[i]==-1)
{
pre[i]=x;
queue[++tail]=i;
}
if(pre[t]!=-1)
break;
}
}
if(pre[t]==-1)
break;
min_flow=inf;
for(x=pre[y=t];y!=s;)
{
if(cap[x][y]<min_flow)
min_flow=cap[x][y];
y=x;
x=pre[y];
}
for(x=pre[y=t];y!=s;)
{
cap[x][y] -= min_flow;
cap[y][x] += min_flow;
y=x;
x=pre[y];
}
max_flow += min_flow;
}
return max_flow;
}
int main(int i,int j,int k)
{
int n1,n2,n3;
char str1[25],str2[25];
while(~scanf("%d",&n1))
{
memset(cap,0,sizeof(cap));
s=1;
t=2;
int num=2;
for(i=1;i<=n1;i++)
{
scanf("%s",str1);
Map[str1]=++num;
cap[num][t]=1;
}
scanf("%d",&n2);
for(j=1;j<=n2;j++)
{
scanf("%s %s",str1,str2);
Map[str1]=++num;
cap[s][num]=1;
if(!Map.count(str2))
{
Map[str2]=++num;
}
cap[Map[str1]][Map[str2]]=1;
}
scanf("%d",&n3);
for(k=1;k<=n3;k++)
{
scanf("%s %s",str1,str2);
if(!Map.count(str1))
{
Map[str1]=++num;
}
if(!Map.count(str2))
{
Map[str2]=++num;
}
cap[Map[str1]][Map[str2]]=inf;
}
n=num;
printf("%d\n",n2-maxflow());
}
return 0;
}