hdu 4292 Food【拆点网络流】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4292

解法:拆人

代码:

#include <stdio.h>
#include <ctime>
#include <math.h>
#include <limits.h>
#include <complex>
#include <string>
#include <functional>
#include <iterator>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <list>
#include <bitset>
#include <sstream>
#include <iomanip>
#include <fstream>
#include <iostream>
#include <ctime>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <time.h>
#include <ctype.h>
#include <string.h>
#include <assert.h>  

using namespace std;

const int MAXN = 50010;//点数的最大值
const int MAXM = 90001000;//边数的最大值
const int INF = 0x3f3f3f3f;

struct Edge
{
    int to, next, cap, flow;
}edge[MAXM];//注意是MAXM
int tol;
int head[MAXN];
int gap[MAXN], dep[MAXN], pre[MAXN], cur[MAXN];
void init()
{
    tol = 0;
    memset(head, -1, sizeof(head));
}
//加边,单向图三个参数,双向图四个参数
void addedge(int u, int v, int w, int rw = 0)
{
    edge[tol].to = v; edge[tol].cap = w; edge[tol].next = head[u];
    edge[tol].flow = 0; head[u] = tol++;
    edge[tol].to = u; edge[tol].cap = rw; edge[tol].next = head[v];
    edge[tol].flow = 0; head[v] = tol++;
}
//输入参数:起点、终点、点的总数
//点的编号没有影响,只要输入点的总数
int sap(int start, int end, int N)
{
    memset(gap, 0, sizeof(gap));
    memset(dep, 0, sizeof(dep));
    memcpy(cur, head, sizeof(head));
    int u = start;
    pre[u] = -1;
    gap[0] = N;
    int ans = 0;
    while (dep[start] < N)
    {
        if (u == end)
        {
            int Min = INF;
            for (int i = pre[u]; i != -1; i = pre[edge[i ^ 1].to])
                if (Min > edge[i].cap - edge[i].flow)
                    Min = edge[i].cap - edge[i].flow;
            for (int i = pre[u]; i != -1; i = pre[edge[i ^ 1].to])
            {
                edge[i].flow += Min;
                edge[i ^ 1].flow -= Min;
            }
            u = start;
            ans += Min;
            continue;
        }
        bool flag = false;
        int v;
        for (int i = cur[u]; i != -1; i = edge[i].next)
        {
            v = edge[i].to;
            if (edge[i].cap - edge[i].flow && dep[v] + 1 == dep[u])
            {
                flag = true;
                cur[u] = pre[v] = i;
                break;
            }
        }
        if (flag)
        {
            u = v;
            continue;
        }
        int Min = N;
        for (int i = head[u]; i != -1; i = edge[i].next)
            if (edge[i].cap - edge[i].flow && dep[edge[i].to] < Min)
            {
                Min = dep[edge[i].to];
                cur[u] = i;
            }
        gap[dep[u]]--;
        if (!gap[dep[u]])return ans;
        dep[u] = Min + 1;
        gap[dep[u]]++;
        if (u != start) u = edge[pre[u] ^ 1].to;
    }
    return ans;
}

int n, f, d;
char s[300];
int F[300], D[300];

int main()
{
    while (~scanf("%d%d%d", &n, &f, &d))
    {
        init();
        for (int i = 1; i <= f; i++) scanf("%d", &F[i]);
        for (int i = 1; i <= d; i++) scanf("%d", &D[i]);

        for (int i = 1; i <= f; i++) addedge(0, i, F[i]);
        for (int i = 1; i <= d; i++) addedge(f + n + n + i, f + n + n + d + 1, D[i]);
        for (int i = 1; i <= n; i++) addedge(f + i, f + n + i, 1);

        for (int i = 1; i <= n; i++)
        {

            scanf("%s", s);
            for (int k = 0; k < f; k++)//食物
            {
                if (s[k] == ‘Y‘)
                    addedge(k + 1, f + i , 1);
            }

        }
        for (int i = 1; i <= n; i++)
        {
            scanf("%s", s);
            for (int k = 0; k < d; k++)//水
            {
                if (s[k] == ‘Y‘)
                    addedge(i + f + n, f + n + n + k + 1, 1);
            }
        }
        int ans = sap(0, f + d + n + n + 1, f + d + n + n + 2);
        printf("%d\n",ans);
    }
    return 0;
}

版权声明:转载请注明出处。

时间: 2024-08-06 12:00:09

hdu 4292 Food【拆点网络流】的相关文章

HDU 4292 Food (拆点最大流)

题意:N个人,F种食物,D种饮料,给定每种食物和饮料的量.每个人有自己喜欢的食物和饮料,如果得到自己喜欢的食物和饮料才能得到满足.求最大满足的人数. 分析:如果只是简单地N个人选择F种食物的话可以用二分图匹配来完成,但是该题种一个人要选择两样东西. 采取以下操作建图: 增加源点和汇点,源点与F个食物相连,每条弧流量为第i种食物的数量:D个食物与汇点相连,每条弧流量为其数量. 所以将N个人拆成两个点,对应两点之间连一条边,流量为1. 然后跑出最大流就是答案. #include<bits/stdc+

hdu 4292 Food 最大流+拆点

Food Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2664    Accepted Submission(s): 899 Problem Description You, a part-time dining service worker in your college's dining hall, are now confus

hdu 4292 网络最大流

http://acm.hdu.edu.cn/showproblem.php?pid=4292 Problem Description You, a part-time dining service worker in your college's dining hall, are now confused with a new problem: serve as many people as possible. The issue comes up as people in your colle

HDU 4888 Redraw Beautiful Drawings 网络流 建图

题意: 给定n, m, k 下面n个整数 a[n] 下面m个整数 b[n] 用数字[0,k]构造一个n*m的矩阵 若有唯一解则输出这个矩阵,若有多解输出Not Unique,若无解输出Impossible 思路:网络流,,, n行当成n个点,m列当成m个点 从行-列连一条流量为k的边,然后源点-行连一条a[i]的边, 列-汇点 流量为b[i] 瞎了,该退役了 T^T #include<stdio.h> #include<string.h> #include<iostream&

HDU 3605Escape(缩点+网络流之最大流)

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=3605 本来打算昨天写两道题的,结果这个题卡住了,最后才发现是最后的判断条件出错了,判断满流的条件应该是与n的比较,竟然写成与所有星球总容量的比较了.(最近大脑短路..) 这题也不是完全自己想的,没想到缩点这一技巧,由于n的数据范围太大,普通的建图方法会超时超内存,需要缩点,因为对于每个点来说,一共只有2^10种方法,而最多一共有10W个点,显然有很多点是重复的,这时可以采取缩点的方法,将重复的当成一

hdu 4292 Food (最大流)

hdu 4292 Food Description You, a part-time dining service worker in your college's dining hall, are now confused with a new problem: serve as many people as possible. The issue comes up as people in your college are more and more difficult to serve w

HDU 4292 Food(建图+最大流)

使用 PVRTC 压缩格式创建纹理(Creating textures in the PVRTC compression format) 太阳火神的美丽人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转载请保留此句:太阳火神的美丽人生 -  本博客专注于 敏捷开发及移动和物联设备研究:iOS.Android.Html5.Arduino.pcDuino,否则,出自本博客的文章拒绝转载或再转载,谢谢合作. 有关该篇

hdu 4292 贪心

http://acm.hdu.edu.cn/showproblem.php?pid=4296 Problem Description Have you ever heard the story of Blue.Mary, the great civil engineer? Unlike Mr. Wolowitz, Dr. Blue.Mary has accomplished many great projects, one of which is the Guanghua Building. T

Food (hdu 4292 网络流sap模板题)

Food Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3102    Accepted Submission(s): 1034 Problem Description You, a part-time dining service worker in your college's dining hall, are now confu