您的位置:首页 > 理论基础 > 计算机网络

HDU-4292-网络流最大流

2016-12-03 15:35 330 查看
题目大意:有n个人,f的food,d的饮料,每个人对事物和饮料有偏好,并且如果一个人没有饮料或者事物他就会离开,问最后最多有几个人留下来;

题目解析:开始是超级食物汇点,中间是人,因为每个人最多选一种食物,所以人与自己也要加一条边,最后是超级饮料汇点,最大流EK即可;

AC代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<queue>
using namespace std;
const int inf=0x3fffffff;
const int maxn=10010;
struct node
{
int to,cap,rev;
node(int a,int b,int c)
{
to=a;
cap=b;
rev=c;
}
};
vector<node>vec[maxn];
int pre[maxn],iter[maxn];
void add_edge(int from,int to,int cost)
{
vec[from].push_back(node(to,cost,vec[to].size()));
vec[to].push_back(node(from,0,vec[from].size()-1));
}
void bfs(int s){
memset(pre,-1,sizeof(pre));
queue<int>que;
pre[s]=0;que.push(s);
while(!que.empty()){
int v=que.front();que.pop();
for(int i=0;i<vec[v].size();i++){
node &e=vec[v][i];
if(e.cap>0&&pre[e.to]<0){
pre[e.to]=pre[v]+1;
que.push(e.to);
}
}
}
}
int dfs(int v,int t,int f){
if(v==t) return f;
for(int &i=iter[v];i<vec[v].size();i++){
node &e=vec[v][i];
if(e.cap>0&&pre[v]<pre[e.to]){
int d=dfs(e.to,t,min(f,e.cap));
if(d>0){
e.cap-=d;
vec[e.to][e.rev].cap+=d;
return d;
}
}
}
return 0;
}
int max_flow(int u,int v)
{
int flow=0;
while(1)
{
bfs(u);
if(pre[v]<0) return flow;
memset(iter,0,sizeof(iter));
int f;
while((f=dfs(u,v,inf))>0) flow+=f;
}
}
int main()
{
int n,i,j,f,d,t;
char str[1001];
while(scanf("%d%d%d",&n,&f,&d)!=EOF)
{
for(i=0;i<maxn;i++)
vec[i].clear();
for(i=1;i<=f;i++)
{
scanf("%d",&t);
add_edge(0,i,t);
}
for(i=1;i<=d;i++)
{
scanf("%d",&t);
add_edge(n+n+f+i,n+n+f+d+1,t);
}
for(i=1;i<=n;i++)
{
add_edge(f+i,f+i+n,1);
}
for(i=1;i<=n;i++)
{
scanf("%s",&str[0]);
for(j=0;j<f;j++)
{
if(str[j]=='Y')
add_edge(j+1,f+i,1);
}
}
for(i=1;i<=n;i++)
{
scanf("%s",&str[0]);
for(j=0;j<d;j++)
{
if(str[j]=='Y')
add_edge(n+f+i,2*n+f+j+1,1);
}
}
int ans=max_flow(0,n+n+f+d+1);
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: