hdu 4292 最大流 水题

很裸的一道最大流

格式懒得排了,注意把人拆成两份,一份连接食物,一份连接饮料

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 }
原文地址:https://www.cnblogs.com/cnblogs321114287/p/4356582.html