题目链接:
http://codeforces.com/gym/100825
题目大意:
N(N<=600)个点,每个点有个名字Si,R(R<=200)个生产商在R个点上,F(F<=200)个工厂在F个点上,不会有一个点既有生产商又有工厂
有T(T<=1000)个公司,每个公司能够到达Ci个点,并且一个只能运输一个生产商的货物。比如生产商1给工厂1运输货物需要用到公司1,那么其余生产商就不能用公司1
一个工厂需要任意一个生产商供应货物,求最多能够给多少个工厂供应货物。
题目思路:
【最大流】
因为一个公司只能被一个生产商使用,所以将每个公司拆点为A入和A出两个点,A入到A出中间流量为1
A公司能够到达的所有点向A入连一条流量为1的边,A出到所能能到达的点连一条流量为1的边。
设置超级源S和超级汇T,超级源S到每一个生产商连一条流量为1的边,每个工厂到超级汇T连一条流量为1的边。
跑一遍最大流即可。
1 // 2 //by coolxxx 3 //#include<bits/stdc++.h> 4 #include<iostream> 5 #include<algorithm> 6 #include<string> 7 #include<iomanip> 8 #include<map> 9 #include<stack> 10 #include<queue> 11 #include<set> 12 #include<bitset> 13 #include<memory.h> 14 #include<time.h> 15 #include<stdio.h> 16 #include<stdlib.h> 17 #include<string.h> 18 //#include<stdbool.h> 19 #include<math.h> 20 #define min(a,b) ((a)<(b)?(a):(b)) 21 #define max(a,b) ((a)>(b)?(a):(b)) 22 #define abs(a) ((a)>0?(a):(-(a))) 23 #define lowbit(a) (a&(-a)) 24 #define sqr(a) ((a)*(a)) 25 #define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b)) 26 #define mem(a,b) memset(a,b,sizeof(a)) 27 #define eps (1e-10) 28 #define J 10000 29 #define mod 1000000007 30 #define MAX 0x7f7f7f7f 31 #define PI 3.14159265358979323 32 #pragma comment(linker,"/STACK:1024000000,1024000000") 33 #define N 3004 34 #define M 5000004 35 using namespace std; 36 typedef long long LL; 37 double anss; 38 LL aans; 39 int cas,cass; 40 int n,m,lll,ans; 41 int S,T,nn,m1,m2; 42 int d[N],vd[N],last[N]; 43 struct xxx 44 { 45 int next,to,q; 46 }a[M]; 47 int ma[N][N]; 48 string ss; 49 string s[N]; 50 map<string,int>id; 51 void add(int x,int y,int z) 52 { 53 a[++lll].to=y; 54 a[lll].q=z; 55 a[lll].next=last[x]; 56 last[x]=lll; 57 } 58 int sap(int u,int f) 59 { 60 int i,v,tt,asp=0,mix=nn-1; 61 if(u==T)return f; 62 for(i=last[u];i!=0;i=a[i].next) 63 { 64 v=a[i].to; 65 if(a[i].q>0) 66 { 67 if(d[u]==d[v]+1) 68 { 69 tt=sap(v,min(f-asp,a[i].q)); 70 asp+=tt; 71 a[i].q-=tt; 72 a[i^1].q+=tt; 73 if(asp==f || d[S]==nn) 74 return asp; 75 } 76 mix=min(mix,d[v]); 77 } 78 } 79 if(asp!=0)return asp; 80 if(!--vd[d[u]])d[S]=nn; 81 else vd[d[u]=mix+1]++; 82 return asp; 83 } 84 int main() 85 { 86 #ifndef ONLINE_JUDGE 87 // freopen("1.txt","r",stdin); 88 // freopen("2.txt","w",stdout); 89 #endif 90 int i,j,k; 91 int x,y,z,f; 92 // init(); 93 // for(scanf("%d",&cass);cass;cass--) 94 // for(scanf("%d",&cas),cass=1;cass<=cas;cass++) 95 // while(~scanf("%s",s)) 96 while(~scanf("%d",&n)) 97 { 98 lll=1; 99 scanf("%d%d%d",&m1,&m2,&m); 100 S=n+m+m+1,T=n+m+m+2; 101 for(i=1;i<=m1;i++) 102 { 103 cin>>ss; 104 if(id.find(ss)==id.end()) 105 id[ss]=++cass; 106 j=id[ss]; 107 add(S,j,1); 108 add(j,S,0); 109 } 110 for(i=1;i<=m2;i++) 111 { 112 cin>>ss; 113 if(id.find(ss)==id.end()) 114 id[ss]=++cass; 115 j=id[ss]; 116 add(j,T,1); 117 add(T,j,0); 118 } 119 for(i=1;i<=m;i++) 120 { 121 add(n+i+i-1,n+i+i,1),add(n+i+i,n+i+i-1,0); 122 scanf("%d",&cas); 123 for(j=1;j<=cas;j++) 124 { 125 cin>>s[j]; 126 if(id.find(s[j])==id.end()) 127 id[s[j]]=++cass; 128 k=id[s[j]]; 129 add(k,n+i+i-1,1),add(n+i+i-1,k,0); 130 add(n+i+i,k,1),add(k,n+i+i,0); 131 } 132 } 133 nn=T; 134 vd[0]=nn; 135 while(d[S]<nn) 136 { 137 f=sap(S,MAX); 138 ans+=f; 139 } 140 printf("%d ",ans); 141 142 cass=0;ans=0; 143 mem(last,0);mem(d,0);mem(vd,0); 144 id.clear(); 145 } 146 return 0; 147 } 148 /* 149 // 150 151 // 152 */