HDU 4292 Food (成都赛区网络赛第五题,拆点网络流)

 

题意:跟POJ3281基本上一样的拆点网络流。

建图:建一超级源点和一超级汇点,源点与食物相连,边权为其数量,汇点与饮料相连,边权也为其数量,把人分成两个点,之间的边权为1。每个人与之需要的食物和饮料相连,边权为1。

代码(SAP模板):

  1 #include <algorithm>

  2 #include <iostream>

  3 #include <cstring>

  4 #include <cstdio>

  5 #include <queue>

  6 using namespace std;

  7 const int maxn=101050;

  8 const int maxm=3000000;

  9 const int oo=1<<30;

 10 int idx,N,F,D;

 11 int cur[maxn],pre[maxn];

 12 int dis[maxn],gap[maxn];

 13 int aug[maxn],head[maxn];

 14 struct Node

 15 {

 16     int u, v, w;

 17     int next;

 18 }edge[maxm];

 19 void addEdge(int u, int v, int w)

 20 {

 21     edge[idx].u=u;

 22     edge[idx].v=v;

 23     edge[idx].w=w;

 24     edge[idx].next=head[u];

 25     head[u]=idx++;

 26     edge[idx].u=v;

 27     edge[idx].v=u;

 28     edge[idx].w=0;

 29     edge[idx].next=head[v];

 30     head[v]=idx++;

 31 }

 32 int SAP(int s,int e,int n)

 33 {

 34     int max_flow=0,v,u=s;

 35     int id,mindis;

 36     aug[s]=oo;

 37     pre[s]=-1;

 38     memset(dis,0,sizeof(dis));

 39     memset(gap,0,sizeof(gap));

 40     gap[0] = n;

 41     for (int i=0;i<=n;i++)

 42     {

 43         cur[i]=head[i];

 44     }

 45     while(dis[s]<n)

 46     {

 47         bool flag=false;

 48         if(u==e)

 49         {

 50             max_flow+=aug[e];

 51             for (v=pre[e];v!=-1;v=pre[v])

 52             {

 53                 id = cur[v];

 54                 edge[id].w-=aug[e];

 55                 edge[id^1].w+=aug[e];

 56                 aug[v]-=aug[e];

 57                 if (edge[id].w==0)

 58                 u=v;

 59             }

 60         }

 61         for(id=cur[u];id!=-1;id=edge[id].next)

 62         {

 63             v=edge[id].v;

 64             if(edge[id].w>0&&dis[u]==dis[v]+1)

 65             {

 66                 flag=true;

 67                 pre[v]=u;

 68                 cur[u]=id;

 69                 aug[v]=min(aug[u], edge[id].w);

 70                 u=v;

 71                 break;

 72             }

 73         }

 74         if (flag==false)

 75         {

 76             if(--gap[dis[u]]==0)

 77             break;

 78             mindis=n;

 79             cur[u]=head[u];

 80             for(id=head[u];id!=-1;id=edge[id].next)

 81             {

 82                 v=edge[id].v;

 83                 if(edge[id].w>0&&dis[v]<mindis)

 84                 {

 85                     mindis=dis[v];

 86                     cur[u]=id;

 87                 }

 88             }

 89             dis[u]=mindis+1;

 90             gap[dis[u]]++;

 91             if(u!=s)

 92             u=pre[u];

 93         }

 94     }

 95     return max_flow;

 96 }

 97 int main()

 98 {

 99     while(~scanf("%d%d%d",&N,&F,&D))

100     {

101         int source=0,sink=N+N+F+D+10;

102         memset(head,-1,sizeof(head));

103         idx=0;

104         int a,b,f,d;

105         int food [10000];

106         int drink[10000];

107         char str[500][500];

108         for(int i=1;i<=F;i++)

109         {

110             scanf("%d",&food[i]);

111             addEdge(source,i,food[i]);

112         }

113         for(int i=1;i<=D;i++)

114         {

115             scanf("%d",&drink[i]);

116             addEdge(i+F,sink,drink[i]);

117         }

118         for(int i=1;i<=N;i++)

119         {

120             addEdge(D+F+i,D+F+N+i,1);

121         }

122         for(int i=1;i<=N;i++)

123         {

124             scanf("%s",str[i]+1);

125             for(int j=1;j<=F;j++)

126             {

127                 if(str[i][j]=='Y')

128                 {

129                     addEdge(j,F+D+i,1);

130                 }

131             }

132         }

133 

134         for(int i=1;i<=N;i++)

135         {

136             scanf("%s",str[i]+1);

137             for(int j=1;j<=D;j++)

138             {

139                 if(str[i][j]=='Y')

140                 {

141                     addEdge(F+D+N+i,F+j,1);

142                 }

143             }

144         }

145         int n=sink+1;

146         printf("%d\n",SAP(source,sink,n));

147     }

148     return 0;

149 }

你可能感兴趣的:(HDU)