• poj1149 最大流好题 难在建图 好题


      这个题的意思是有M个猪圈, N个人, 每个人按次序可以访问一些猪圈并可以买走一定数量的猪, 并且一个人用自己所拥有的猪圈钥匙打开猪圈后这些猪可以重新分配到已经打开的猪圈中, 问你可以买的最多的猪是多少个?强烈推荐看这个博文, 非常感谢博主

    http://ycool.com/post/zhhrrm6
    

      代码如下:

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <queue>
    
    using namespace std;
    const int inf = 0x3fffffff;
    const int maxn = 2000+10;
    
    struct Dinic
    {
        int n;
        struct edge { int from, to, cap; };
        vector<int> G[maxn];
        vector<edge> e;
        int level[maxn], iter[maxn];
        void init()
        {
            for(int i=0; i<=n; i++) G[i].clear();
            e.clear();
        }
        void add_edge(int u, int v, int cap)
        {
            e.push_back((edge){u, v, cap});
            e.push_back((edge){v, u, 0});
            int m = e.size();
            G[u].push_back(m-2);
            G[v].push_back(m-1);
        }
        void bfs(int s)
        {
            memset(level, -1, sizeof(level));
            queue<int> que;
            level[s] = 0;
            que.push(s);
            while(!que.empty())
            {
                int u = que.front();  que.pop();
                for(int i=0; i<G[u].size(); i++)
                {
                    edge &te = e[G[u][i]];
                    if(te.cap>0 && level[te.to]<0)
                    {
                        level[te.to] = level[u] + 1;
                        que.push(te.to);
                    }
                }
            }
        }
        int dfs(int v, int t, int f)
        {
            if(v == t) return f;
            for(int &i=iter[v]; i<G[v].size(); i++)
            {
                edge& tpe = e[G[v][i]];
                if(tpe.cap>0 && level[v]<level[tpe.to])
                {
                    int d = dfs(tpe.to, t, min(f, tpe.cap));
                    if(d > 0)
                    {
                        tpe.cap -= d;
                        e[G[v][i]^1].cap += d;
                        return d;
                    }
                }
            }
            return 0;
        }
        int max_flow(int s, int t)
        {
            int flow = 0;
            for(;;)
            {
                bfs(s);
                if(level[t]<0) return flow;
                memset(iter, 0, sizeof(iter));
                int f;
                while((f=dfs(s, t, 0x3fffffff)) > 0)
                    flow += f;
            }
            return flow;
        }
    }di;
    int pignum[1000+10];
    int f[1000+10];       //i猪圈最后访问的人是哪一个
    int G[105][105];
    
    int main()
    {
        int M, N;
        scanf("%d%d", &M, &N);
        di.n = N+2;   //0超级源点 N+1超级汇点
        di.init();
        for(int i=1; i<=M; i++) scanf("%d", &pignum[i]);
        memset(f, -1, sizeof(f));
        memset(G, -1, sizeof(G));
        for(int i=1; i<=N; i++)
        {
            int v = i;
            int keynum;
            scanf("%d", &keynum);
            for(int i=0; i<keynum; i++)
            {
                int u = 0, t, cap;
                scanf("%d", &t);
                if(f[t] == -1)
                {
                    cap = pignum[t];
                    G[u][v] = (G[u][v]==-1?cap:G[u][v]+cap);
                    f[t] = v;
                }
                else
                {
                    u = f[t];
                    cap = inf;
                    G[u][v] = inf;
                    f[t] = v;
                }
            }
            int ndnum;
            scanf("%d", &ndnum);
            G[v][N+1] = ndnum;
        }
        for(int i=0; i<N+2; i++)
            for(int j=0; j<N+2; j++) if(G[i][j] != -1)
            di.add_edge(i, j, G[i][j]);
        printf("%d
    ", di.max_flow(0, N+1));
        return 0;
    }
  • 相关阅读:
    luogu3242 接水果 (整体二分+树状数组)
    [BZOJ3449] [Usaco2014 Feb]Secret Code
    [BZOJ2821] 作诗(Poetize)
    [BZOJ2434] [Noi2011]阿狸的打字机
    [BZOJ1212] [HNOI2004]L语言
    [JZOJ100026]【NOIP2017提高A组模拟7.7】图
    [BZOJ2467] [中山市选2010]生成树
    [Luogu3868] [TJOI2009]猜数字
    [POJ1006] Biorhythms
    [BZOJ2733] [HNOI2012]永无乡
  • 原文地址:https://www.cnblogs.com/xingxing1024/p/5237212.html
Copyright © 2020-2023  润新知