您的位置:首页 > 其它

POJ 3281 Dining (最大流)

2017-05-02 17:55 387 查看
题意:有F种食物和D种饮料,每种食物或饮料只能供一头牛享用,且每头牛只享用一种食物和一种饮料。现在有n头牛,每头牛都有自

己喜欢的食物种类列表和饮料种类列表,问最多能使几头牛同时享用到自己喜欢的食物和饮料。(1 <= f <= 100, 1 <= d <= 100, 1 <= n <= 100)

思路:巧在建图

见白书:



代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
const int maxn = 505;
const int INF = 0x3f3f3f3f;
int g[maxn][maxn], n, f, d;
int path[maxn], flow[maxn];
int start, endd;
//f+1 - f+1+n 食物一侧的牛
//f+n+1 - f+2n+1 饮料一侧的牛
//1 - f 食物
//f+2n+1 - f+2n+d 饮料
//start:0, enddd:f+2n+d+1

int bfs()
{
queue<int> q;
memset(path, -1, sizeof(path));
path[start] = 0, flow[start] = INF;
q.push(start);
while(!q.empty())
{
int t = q.front(); q.pop();
if(t == endd) break;
for(int i = 0; i <= endd; i++)
{
if(path[i] == -1 && g[t][i])
{
flow[i] = min(flow[t], g[t][i]);
q.push(i);
path[i] = t;
}
}
}
if(path[endd] == -1) return -1;
return flow[endd];
}

int E_K()
{
int max_flow = 0, step, now, pre;
while((step=bfs()) != -1)
{
max_flow += step;
now = endd;
while(now != start)
{
pre = path[now];
g[pre][now] -= step;
g[now][pre] += step;
now = pre;
}
}
return max_flow;
}

int main(void)
{
while(cin >> n >> f >> d)
{
start = 0;
endd = f+d+2*n+1;
memset(g, 0, sizeof(g));
//start - food
for(int i = 1; i <= f; i++)
g[0][i] = 1;
//cow1 - cow2
for(int i = f+1; i <= f+n; i++)
g[i][i+n] = 1;
//drink - endd
for(int i = f+2*n+1; i <= f+2*n+d; i++)
g[i][endd] = 1;
for(int i = 0; i < n; i++)
{
int x, numf, numd;
scanf("%d%d", &numf, &numd);
for(int j = 0; j < numf; j++)
{
scanf("%d", &x);
g[x][f+1+i] = 1;
}
for(int j = 0; j < numd; j++)
{
scanf("%d", &x);
g[f+n+1+i][f+2*n+x] = 1;
}
}
printf("%d\n", E_K());
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  最大流