poj 1087 最大流

时间:2023-03-08 21:05:22

没啥好说的,慢慢建图

Sample Input

4
A
B
C
D
5
laptop B
phone C
pager B
clock B
comb X
3
B X
X A
X D

Sample Output

1

题意:有n个不同的插座,有m台不同的机器需要m种插头,有k组转换:插头A能由插头B转换而来。问这些机器最少有几台不能插上插座。

 #include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
using namespace std;
const int MAXN=;
const int INF=0x3fffffff;
int g[MAXN][MAXN];//存边的容量,没有边的初始化为0
int path[MAXN],flow[MAXN],start,end;
int n;//点的个数,编号0-n.n包括了源点和汇点。
queue<int>q;
int bfs()
{
int i,t;
while(!q.empty())q.pop();//把清空队列
memset(path,-,sizeof(path));//每次搜索前都把路径初始化成-1
path[start]=;
flow[start]=INF;//源点可以有无穷的流流进
q.push(start);
while(!q.empty())
{
t=q.front();
q.pop();
if(t==end)break;
//枚举所有的点,如果点的编号起始点有变化可以改这里
for(i=;i<=n;i++)
{
if(i!=start&&path[i]==-&&g[t][i])
{
flow[i]=flow[t]<g[t][i]?flow[t]:g[t][i];
q.push(i);
path[i]=t;
}
}
}
if(path[end]==-)return -;//即找不到汇点上去了。找不到增广路径了
return flow[end];
}
int Edmonds_Karp()
{
int max_flow=;
int step,now,pre;
while((step=bfs())!=-)
{
max_flow+=step;
now=end;
while(now!=start)
{
pre=path[now];
g[pre][now]-=step;
g[now][pre]+=step;
now=pre;
}
}
return max_flow;
} map<string,int> hash;
int main()
{
int i,j,k,m;
//freopen("1.in","r",stdin);
while(scanf("%d",&n)!=EOF)
{
hash.clear();
memset(g,,sizeof(g));
string s1,s2,s3;
start=;
end=;
int tot=;
while(n--)
{
cin>>s1;
hash[s1]=tot;
g[][hash[s1]]=;
tot++;
}
scanf("%d",&m);
for(i=;i<m;i++)
{
cin>>s1>>s2;
if(hash[s1]==) hash[s1]=tot++;
if(hash[s2]==) hash[s2]=tot++;
g[hash[s1]][end]=;
g[hash[s2]][hash[s1]]=;
}
scanf("%d",&k);
while(k--)
{
cin>>s1>>s2;
if(hash[s1]==) hash[s1]=tot++;
if(hash[s2]==) hash[s2]=tot++;
g[hash[s2]][hash[s1]]=INF;
}
n=tot-; //总点数
printf("%d\n",m-Edmonds_Karp());
}
return ;
}