#include<stdio.h>
#include <vector>
#include <string.h>
#include<iostream>
#include <queue>
#define max_V 410
using namespace std;
struct edge
{
int to,cap,rev;//终点 容量 反向边
};
vector<edge> G[max_V];
bool used[max_V];
void add_edge(int from ,int to, int cap)
{
G[from].push_back((edge){to,cap,G[to].size()});
G[to].push_back((edge){from,0,G[from].size()-1});
}
//深搜找增广路
int dfs(int v,int t,int f)
{
if(v==t)return f;
used[v]=true;
for(int i=0;i<G[v].size();i++)
{
edge &e=G[v][i];
if(!used[e.to]&&e.cap>0)
{
int d=dfs(e.to,t,min(f,e.cap));
if(d>0)
{
e.cap-=d;
G[e.to][e.rev].cap+=d;
return d;
}
}
}
return 0;
}
int max_flow(int s,int t)//最大流求解
{
int flow = 0;
while(1)
{
memset(used,0,sizeof(used));
int f=dfs(s,t,100000);
if(f==0)return flow;
flow+=f;
}
}
int N,F,D;
bool likeF[120][120];
bool likeD[120][120];
void solve()
{
int s=N*2+F+D,t=s+1;
for(int i=0;i<F;i++)
{
add_edge(s,N*2+i,1);
}
for(int i=0;i<N;i++)
{
add_edge(i,N+i,1);
}
for(int i=0;i<D;i++)
add_edge(i+2*N+F,t,1);
for(int i=0;i<N;i++)
{
for(int j=0;j<F;j++)
if(likeF[i][j])add_edge(2*N+j,i,1);
for(int j=0;j<D;j++)
if(likeD[i][j])add_edge(N+i,2*N+F+j,1);
}
printf("%d\n",max_flow(s,t));
}
int main()
{
while(~scanf("%d%d%d",&N,&F,&D))
{memset(likeF,0,sizeof(likeF));
memset(likeD,0,sizeof(likeD));
for(int i=0;i<N;i++)
{
int a,b,a1;
scanf("%d%d",&a,&a1);
for(int j=0;j<a;j++)
{scanf("%d",&b);
likeF[i][b-1]=1;
}
for(int j=0;j<a1;j++)
{scanf("%d",&b);
likeD[i][b-1]=1;
}
}
solve();}
return 0;
}
poj3281 - Dining (但求心安)
最新推荐文章于 2020-06-13 19:48:37 发布