POJ-1087 A Plug for UNIX
阿新 • • 發佈:2018-11-10
簡單的網路流問題,就是建圖麻煩一些
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<map> using namespace std; typedef long long ll; const int N=500+10; const int M=800+10; //都開大一點 const int INF=0x7f7f7f7f; struct Edge { int to,nxt,cap,flow; }edge[M]; int tot,first[N]; void addedge(int u,int v,int w,int rw=0) { edge[tot].to=v;edge[tot].cap=w;edge[tot].flow=0; edge[tot].nxt=first[u];first[u]=tot++; edge[tot].to=u;edge[tot].cap=rw;edge[tot].flow=0; edge[tot].nxt=first[v];first[v]=tot++; } void init() { tot=0; memset(first,-1,sizeof(first)); } int gap[N],dep[N],cur[N],pre[N]; int sap(int s,int e,int n) { memset(gap,0,sizeof(gap)); memset(dep,0,sizeof(dep)); memcpy(cur,first,sizeof(first)); int u=s; pre[u]=-1; gap[0]=n; int ans=0; while(dep[s]<n) { if(u==e) { int Min=INF; for(int i=pre[u];i!=-1;i=pre[edge[i^1].to]) if(edge[i].cap-edge[i].flow<Min) Min=edge[i].cap-edge[i].flow; for(int i=pre[u];i!=-1;i=pre[edge[i^1].to]) { edge[i].flow+=Min; edge[i^1].flow-=Min; } ans+=Min; u=s; continue; } bool flag=false; int v; for(int i=cur[u];i!=-1;i=edge[i].nxt) { v=edge[i].to; if(edge[i].cap-edge[i].flow&&dep[v]+1==dep[u]) { flag=true; cur[u]=pre[v]=i; break; } } if(flag) { u=v; continue; } gap[dep[u]]--; if(!gap[dep[u]]) return ans; int Min=n; for(int i=first[u];i!=-1;i=edge[i].nxt) if(edge[i].cap-edge[i].flow&&dep[edge[i].to]<Min) { Min=dep[edge[i].to]; cur[u]=i; } dep[u]=Min+1; gap[dep[u]]++; if(u!=s) u=edge[pre[u]^1].to; } return ans; } int num[N]; int main() { int n,m,k; string s,s0; map<string,int> mm; int cnt=1; init(); memset(num,0,sizeof(num)); scanf("%d",&n); for(int i=0;i<n;i++) { cin>>s; if(!mm[s]) mm[s]=cnt++; num[mm[s]]++; } for(int i=1;i<cnt;i++) addedge(0,i,num[i]); scanf("%d",&m); n=cnt-1; int e=n+m+1; for(int i=0;i<m;i++) { cin>>s; cin>>s; if(!mm[s]) //隨時可能出現新的插座,要新加編號 { mm[s]=m+1+cnt++; } addedge(mm[s],n+i+1,1); addedge(n+i+1,e,1); } scanf("%d",&k); for(int i=0;i<k;i++) { cin>>s0>>s; if(!mm[s0]) { mm[s0]=m+1+cnt++; } if(!mm[s]) { mm[s]=m+1+cnt++; } addedge(mm[s],mm[s0],INF); } printf("%d\n",m-sap(0,e,m+1+cnt)); return 0; }