很裸的一道最大流
格式懒得排了,注意把人拆成两份,一份连接食物,一份连接饮料
4 3 3 //4个人,3种食物,3种饮料 1 1 1 //食物每种分别为1 1 1 1 //饮料每种数目分别为1 YYN //第一个人对第1,2,3种食物的态度为接受,接受和拒绝 NYY YNY YNY YNY //第一个人对第1,2,3种饮料的态度为接受,拒绝和接受 YYN YYN NNY
3
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 using namespace std; 8 const int maxn=11005; 9 const int MAXN = 10010;//点数的最大值 10 const int MAXM = 400010;//边数的最大值 11 const int INF = 0x3f3f3f3f; 12 struct Edge 13 { 14 int to,next,cap,flow; 15 }edge[MAXM];//注意是MAXM 16 int tol; 17 int head[MAXN]; 18 int gap[MAXN],dep[MAXN],cur[MAXN]; 19 void init() 20 { 21 tol = 0; 22 memset(head,-1,sizeof(head)); 23 } 24 void addedge(int u,int v,int w,int rw = 0) 25 { 26 edge[tol].to = v; edge[tol].cap = w; edge[tol].flow = 0; 27 edge[tol].next = head[u]; head[u] = tol++; 28 edge[tol].to = u; edge[tol].cap = rw; edge[tol].flow = 0; 29 edge[tol].next = head[v]; head[v] = tol++; 30 } 31 int Q[MAXN]; 32 void BFS(int start,int end) 33 { 34 memset(dep,-1,sizeof(dep)); 35 memset(gap,0,sizeof(gap)); 36 gap[0] = 1; 37 int front = 0, rear = 0; 38 dep[end] = 0; 39 Q[rear++] = end; 40 while(front != rear) 41 { 42 int u = Q[front++]; 43 for(int i = head[u]; i != -1; i = edge[i].next) 44 { 45 int v = edge[i].to; 46 if(dep[v] != -1)continue; 47 Q[rear++] = v; 48 dep[v] = dep[u] + 1; 49 gap[dep[v]]++; 50 } 51 } 52 } 53 int S[MAXN]; 54 int sap(int start,int end,int N) 55 { 56 BFS(start,end); 57 memcpy(cur,head,sizeof(head)); 58 int top = 0; 59 int u = start; 60 int ans = 0; 61 while(dep[start] < N) 62 { 63 if(u == end) 64 { 65 int Min = INF; 66 int inser; 67 for(int i = 0;i < top;i++) 68 if(Min > edge[S[i]].cap - edge[S[i]].flow) 69 { 70 Min = edge[S[i]].cap - edge[S[i]].flow; 71 inser = i; 72 } 73 for(int i = 0;i < top;i++) 74 { 75 edge[S[i]].flow += Min; 76 edge[S[i]^1].flow -= Min; 77 } 78 ans += Min; 79 top = inser; 80 u = edge[S[top]^1].to; 81 continue; 82 } 83 bool flag = false; 84 int v; 85 for(int i = cur[u]; i != -1; i = edge[i].next) 86 { 87 v = edge[i].to; 88 if(edge[i].cap - edge[i].flow && dep[v]+1 == dep[u]) 89 { 90 flag = true; 91 cur[u] = i; 92 break; 93 } 94 } 95 if(flag) 96 { 97 S[top++] = cur[u]; 98 u = v; 99 continue; 100 } 101 int Min = N; 102 for(int i = head[u]; i != -1; i = edge[i].next) 103 if(edge[i].cap - edge[i].flow && dep[edge[i].to] < Min) 104 { 105 Min = dep[edge[i].to]; 106 cur[u] = i; 107 } 108 gap[dep[u]]--; 109 if(!gap[dep[u]])return ans; 110 dep[u] = Min + 1; 111 gap[dep[u]]++; 112 if(u != start)u = edge[S[--top]^1].to; 113 } 114 return ans; 115 } 116 int g[2000][2000]; 117 int main() 118 { 119 int i,j,k; 120 #ifndef ONLINE_JUDGE 121 freopen("1.in","r",stdin); 122 #endif 123 int n,d,f; 124 while(scanf("%d%d%d",&n,&f,&d)!=EOF) 125 { 126 init(); 127 memset(g,0,sizeof(g)); 128 int start=0; 129 int end=f+d+2*n+1; 130 for(i=1;i<=f;i++) 131 { 132 scanf("%d",&g[0][i]); 133 addedge(0,i,g[0][i]); 134 } 135 for(i=f+2*n+1;i<=f+2*n+d;i++) 136 { 137 scanf("%d",&g[i][1]); 138 addedge(i,end,g[i][1]); 139 } 140 for(i=1;i<=n;i++) 141 { 142 addedge(f+i*2-1,f+i*2,1); 143 } 144 char s[250]; 145 for(i=1;i<=n;i++) 146 { 147 scanf("%s",s); 148 for(int j=0;j<f;j++) 149 { 150 if(s[j]=='Y') 151 { 152 addedge(j+1,f+2*i-1,1); 153 } 154 } 155 } 156 for(i=1;i<=n;i++) 157 { 158 scanf("%s",s); 159 for(int j=0;j<d;j++) 160 { 161 if(s[j]=='Y') 162 { 163 addedge(f+2*i,f+2*n+j+1,1); 164 } 165 } 166 } 167 printf("%d ",sap(start,end,d+f+2*n+1)); 168 } 169 return 0; 170 }