A Plug for UNIX UVA
阿新 • • 發佈:2018-12-13
題目大意:
給你一些插座和一些插頭一些轉換器,可以將一些插頭上插上轉化器使其變成另一種插頭。問最多可以讓多少的插頭插座匹配。
思路:
轉換器轉換的兩種插頭之間連上一條容量無限大的邊,同名的插頭插座之間連上容量為1的邊。將插座連上s點,插頭連上t跑最大流即可。
#include<iostream> #include<cstdio> #include<algorithm> #include<queue> #include<cstring> #include<string> #include<map> using namespace std; map<string,int> NO,NOin; const int maxn=505;//µãÊý£¬×î´óֵΪ2010 const int maxm=50005;//±ßÊý£¬×î´óֵΪ1200010 const int inf=0x3f3f3f3f; struct Edge{ int to,nxt,cap,flow; }edge[maxm]; int tol; int head[maxn]; void init(){ tol=2; memset(head,-1,sizeof(head)); } void addedge(int u,int v,int w,int rw=0){ edge[tol].to=v;edge[tol].cap=w;edge[tol].flow=0; edge[tol].nxt=head[u];head[u]=tol++; edge[tol].to=u;edge[tol].cap=rw;edge[tol].flow=0; edge[tol].nxt=head[v];head[v]=tol++; } int Q[maxn]; int dep[maxn],cur[maxn],sta[maxn]; bool bfs(int s,int t,int n){ int front=0,tail=0; memset(dep,-1,sizeof(dep[0])*(n+1)); dep[s]=0; Q[tail++]=s; while(front<tail){ int u=Q[front++]; for(int i=head[u];i!=-1;i=edge[i].nxt){ int v=edge[i].to; if(edge[i].cap>edge[i].flow&&dep[v]==-1){ dep[v]=dep[u]+1; if(v==t) return true; Q[tail++]=v; } } } return false; } int dinic(int s,int t,int n){ int maxflow=0; while(bfs(s,t,n)){ for(int i=0;i<n;i++) cur[i]=head[i]; int u=s,tail=0; while(cur[s]!=-1){ if(u==t){ int tp=inf; for(int i=tail-1;i>=0;i--) { tp=min(tp,edge[sta[i]].cap-edge[sta[i]].flow); } maxflow+=tp; for(int i=tail-1;i>=0;i--){ edge[sta[i]].flow+=tp; edge[sta[i]^1].flow-=tp; if(edge[sta[i]].cap-edge[sta[i]].flow==0) tail=i; } u=edge[sta[tail]^1].to; } else if(cur[u]!=-1&&edge[cur[u]].cap>edge[cur[u]].flow&&dep[u]+1==dep[edge[cur[u]].to]){ sta[tail++]=cur[u]; u=edge[cur[u]].to; } else{ while(u!=s&&cur[u]==-1) u=edge[sta[--tail]^1].to; cur[u] = edge [cur[u]].nxt; } } } return maxflow; } string rec[105],plu[105]; int main() { int t; scanf("%d",&t); for(int kace=1;kace<=t;kace++){ int n; int cnt=1; NO.clear(),NOin.clear(); init(); int ss=0,tt=500; scanf("%d",&n); for(int i=1;i<=n;i++) { cin>>rec[i]; if(!NO.count(rec[i])){ NO[rec[i]]=cnt++; } addedge(NO[rec[i]],tt,1); } int m; scanf("%d",&m); for(int i=1;i<=m;i++) { string s; cin>>s>>plu[i]; if(!NOin.count(plu[i])){ NOin[plu[i]]=cnt++; } addedge(ss,NOin[plu[i]],1); if(NO.count(plu[i])) addedge(NOin[plu[i]],NO[plu[i]],inf); } int k; scanf("%d",&k); for(int i=1;i<=k;i++) { string s1,s2; cin>>s1>>s2; if(!NOin.count(s1)){ NOin[s1]=cnt++; } if(!NOin.count(s2)){ NOin[s2]=cnt++; } addedge(NOin[s1],NOin[s2],inf); if(NO.count(s2)) addedge(NOin[s2],NO[s2],inf); } if(kace>1) printf("\n"); printf("%d\n",m-dinic(ss,tt,501)); } }