POJ1087 A Plug of UNIX
你作为某高管去住宿了,然后宾馆里有几种插座,分别有其对应型号,你携带了几种用电器(手机,电脑一类的),也有其对应型号;可是不一定用电器就能和插座匹配上,于是宾馆的商店里提供了一些转换器,这些转换器可以将某一型号电源转换成另一型号的。问,你的用电器最少会有多少种无法充电
源点向电器连边,容量为1,电器向对应的插座连边,容量为1,对于转换器,在插座与插座之间连边,容量为inf,所有插座向汇点连边,容量为插座的个数~
#include<cstdio> #include<algorithm> #include<queue> #include<cstring> #include<map> #include<iostream> #include<string> using namespace std; const int maxn=1014; const int inf=1e9; queue<int> q; int n; int g[maxn][maxn]; int pre[maxn]; int flow[maxn]; int maxflow; int bfs (int s,int t) { while (!q.empty()) q.pop(); for (int i=0;i<=n;i++) pre[i]=-1; pre[s]=0; q.push(s); flow[s]=inf; while (!q.empty()) { int x=q.front(); q.pop(); if (x==t) break; for (int i=0;i<=n;i++) if (g[x][i]>0&&pre[i]==-1) { pre[i]=x; flow[i]=min(flow[x],g[x][i]); q.push(i); } } if (pre[t]==-1) return -1; else return flow[t]; } void Edmonds_Karp (int s,int t) { int increase=0; while ((increase=bfs(s,t))!=-1) { int k=t; while (k!=s) { int last=pre[k]; g[last][k]-=increase; g[k][last]+=increase; k=last; } maxflow+=increase; } } map<string,int> pos; int main () { string s1,s2; int N,M,cnt,st,ed; while (~scanf("%d",&N)) { pos.clear(); memset(g,0,sizeof(g)); maxflow=0; st=0; ed=1; cnt=2; while (N--) { cin>>s1; pos[s1]=cnt; g[0][cnt++]=1; } scanf ("%d",&M); for (int i=0;i<M;i++) { cin>>s1>>s2; if (pos[s1]==0) pos[s1]=cnt++; if (pos[s2]==0) pos[s2]=cnt++; g[pos[s1]][ed]=1; g[pos[s2]][pos[s1]]=1; } scanf ("%d",&N); while (N--) { cin>>s1>>s2; if (pos[s1]==0) pos[s1]=cnt++; if (pos[s2]==0) pos[s2]=cnt++; g[pos[s2]][pos[s1]]=inf; } n=cnt-1; Edmonds_Karp (st,ed); printf ("%d\n",M-maxflow); } return 0; }