poj 1087 A Plug for UNIX(最大流)

来源:互联网 发布:阿里云专有网络 收费 编辑:程序博客网 时间:2024/05/22 02:03

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;}