HDU4292-Food-网络流
裸网络流题。
1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 #include <queue> 5 using namespace std; 6 7 const int maxn = 1200; 8 const int maxe = 500000; 9 const int inf = 1<<30; 10 11 struct Edge 12 { 13 int v,cap,next; 14 }edge[maxe]; 15 int level[maxn]; 16 int gap[maxn],pre[maxn],cur[maxn],head[maxn]; 17 18 int NV,NE; 19 20 void add_edge(int u,int v,int cap) 21 { 22 edge[NE].v=v; 23 edge[NE].cap=cap; 24 edge[NE].next=head[u]; 25 head[u]=NE++; 26 27 edge[NE].v=u; 28 edge[NE].cap=0; 29 edge[NE].next=head[v]; 30 head[v]=NE++; 31 } 32 33 void bfs(int vt) 34 { 35 memset(level,-1,sizeof(level)); 36 memset(gap,0,sizeof(gap)); 37 level[vt]=0; 38 gap[level[vt]]++; 39 queue<int>que; 40 que.push(vt); 41 while(!que.empty()) { 42 int u=que.front(); 43 que.pop(); 44 for(int i=head[u]; i!=-1; i=edge[i].next) { 45 int v=edge[i].v; 46 if(level[v]!=-1)continue; 47 level[v]=level[u]+1; 48 gap[level[v]]++; 49 que.push(v); 50 51 } 52 } 53 } 54 55 int SAP(int vs,int vt) 56 { 57 bfs(vt); 58 memset(pre,-1,sizeof(pre)); 59 memcpy(cur,head,sizeof(head)); 60 int u=pre[vs]=vs,flow=0,aug=inf; 61 gap[0]=NV; 62 while(level[vs]<NV) { 63 bool flag=false; 64 for(int &i=cur[u]; i!=-1; i=edge[i].next) { 65 int v=edge[i].v; 66 if(edge[i].cap&&level[u]==level[v]+1) { 67 flag=true; 68 pre[v]=u; 69 u=v; 70 // aug=(aug==-1?edge[i].cap:min(aug,edge[i].cap)); 71 aug=min(aug,edge[i].cap); 72 if(v==vt) { 73 flow+=aug; 74 for(u=pre[v]; v!=vs; v=u,u=pre[u]) { 75 edge[cur[u]].cap-=aug; 76 edge[cur[u]^1].cap+=aug; 77 } 78 // aug=-1; 79 aug=inf; 80 } 81 break; 82 } 83 } 84 if(flag)continue; 85 int minlevel=NV; 86 for(int i=head[u]; i!=-1; i=edge[i].next) { 87 int v=edge[i].v; 88 if(edge[i].cap&&level[v]<minlevel) { 89 minlevel=level[v]; 90 cur[u]=i; 91 } 92 } 93 if(--gap[level[u]]==0)break; 94 level[u]=minlevel+1; 95 gap[level[u]]++; 96 u=pre[u]; 97 } 98 return flow; 99 } 100 101 int N,F,D; 102 103 int main() 104 { 105 while(~scanf("%d%d%d",&N,&F,&D)) 106 { 107 memset(head,-1,sizeof head); 108 NV = 2*N+F+D+1;NE=0; 109 int t; 110 char op[300]; 111 for(int i=1;i<=F;i++) 112 { 113 scanf("%d",&t); 114 add_edge(0,i,t); 115 } 116 for(int i=1;i<=D;i++) 117 { 118 scanf("%d",&t); 119 add_edge(i+F,NV,t); 120 } 121 for(int i=1;i<=N;i++) 122 { 123 scanf("%s",op); 124 for(int j=1;j<=F;j++) 125 if(op[j-1] == 'Y') 126 add_edge(j,i*2-1+D+F,1); 127 } 128 for(int i=1;i<=N;i++) 129 add_edge(i*2-1+D+F,i*2+D+F,1); 130 131 for(int i=1;i<=N;i++) 132 { 133 scanf("%s",op); 134 for(int j=1;j<=D;j++) 135 if(op[j-1] == 'Y') 136 add_edge(i*2+D+F,j+F,1); 137 } 138 printf("%d\n",SAP(0,NV)); 139 } 140 } 141 /* 142 4 3 3 143 1 1 1 144 1 1 1 145 YYN 146 NYY 147 YNY 148 YNY 149 YNY 150 YYN 151 YYN 152 NNY 153 */