HDU4292-Food-网络流

时间:2023-03-10 05:51:45
HDU4292-Food-网络流

裸网络流题。

 #include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std; const int maxn = ;
const int maxe = ;
const int inf = <<; struct Edge
{
int v,cap,next;
}edge[maxe];
int level[maxn];
int gap[maxn],pre[maxn],cur[maxn],head[maxn]; int NV,NE; void add_edge(int u,int v,int cap)
{
edge[NE].v=v;
edge[NE].cap=cap;
edge[NE].next=head[u];
head[u]=NE++; edge[NE].v=u;
edge[NE].cap=;
edge[NE].next=head[v];
head[v]=NE++;
} void bfs(int vt)
{
memset(level,-,sizeof(level));
memset(gap,,sizeof(gap));
level[vt]=;
gap[level[vt]]++;
queue<int>que;
que.push(vt);
while(!que.empty()) {
int u=que.front();
que.pop();
for(int i=head[u]; i!=-; i=edge[i].next) {
int v=edge[i].v;
if(level[v]!=-)continue;
level[v]=level[u]+;
gap[level[v]]++;
que.push(v); }
}
} int SAP(int vs,int vt)
{
bfs(vt);
memset(pre,-,sizeof(pre));
memcpy(cur,head,sizeof(head));
int u=pre[vs]=vs,flow=,aug=inf;
gap[]=NV;
while(level[vs]<NV) {
bool flag=false;
for(int &i=cur[u]; i!=-; i=edge[i].next) {
int v=edge[i].v;
if(edge[i].cap&&level[u]==level[v]+) {
flag=true;
pre[v]=u;
u=v;
// aug=(aug==-1?edge[i].cap:min(aug,edge[i].cap));
aug=min(aug,edge[i].cap);
if(v==vt) {
flow+=aug;
for(u=pre[v]; v!=vs; v=u,u=pre[u]) {
edge[cur[u]].cap-=aug;
edge[cur[u]^].cap+=aug;
}
// aug=-1;
aug=inf;
}
break;
}
}
if(flag)continue;
int minlevel=NV;
for(int i=head[u]; i!=-; i=edge[i].next) {
int v=edge[i].v;
if(edge[i].cap&&level[v]<minlevel) {
minlevel=level[v];
cur[u]=i;
}
}
if(--gap[level[u]]==)break;
level[u]=minlevel+;
gap[level[u]]++;
u=pre[u];
}
return flow;
} int N,F,D; int main()
{
while(~scanf("%d%d%d",&N,&F,&D))
{
memset(head,-,sizeof head);
NV = *N+F+D+;NE=;
int t;
char op[];
for(int i=;i<=F;i++)
{
scanf("%d",&t);
add_edge(,i,t);
}
for(int i=;i<=D;i++)
{
scanf("%d",&t);
add_edge(i+F,NV,t);
}
for(int i=;i<=N;i++)
{
scanf("%s",op);
for(int j=;j<=F;j++)
if(op[j-] == 'Y')
add_edge(j,i*-+D+F,);
}
for(int i=;i<=N;i++)
add_edge(i*-+D+F,i*+D+F,); for(int i=;i<=N;i++)
{
scanf("%s",op);
for(int j=;j<=D;j++)
if(op[j-] == 'Y')
add_edge(i*+D+F,j+F,);
}
printf("%d\n",SAP(,NV));
}
}
/*
4 3 3
1 1 1
1 1 1
YYN
NYY
YNY
YNY
YNY
YYN
YYN
NNY
*/