zoukankan      html  css  js  c++  java
  • POJ-3821-Dining (拆点网络流)

    这题为什么不能用 左边放食物,中间放牛,后面放水?
    原因很简单,假设一头牛喜欢两个食物AB和两种水AB。
    此时可以从一个食物A,走到牛A,再走到水A。
    但是还可以有另一条路,从另一个食物B,走到该牛A,并走到该牛喜欢的另一个水B。
    这是错误的原因之一,其实也跟反边有关。
    所以对于牛,拆开,中间建立一条边,说明该牛已经使用过,这样也避免了从其它食物C走到牛A,此时我们希望它走反边,即牛A到食物A,再从食物A走向其它牛等等,但是却在到达牛A的时候,走向了水B的情况。

    #include <iostream>
    #include <stdio.h>
    #include <queue>
    #include <string.h>
    using namespace std;
    
    int n,f,d,fi,di;
    const int INF=0x3f3f3f3f;
    const int maxn=110;
    
    struct Edge {
        int to,cap,flow;
    };
    
    struct Dinic {
        int s,t,cnt;
        Edge edge[maxn*maxn*2];
        int head[maxn*4];
        int next[maxn*maxn*2];
        int deep[maxn*4];
        int cur[maxn*4];
        bool vis[maxn*4];
    
        void addEdge(int u,int v,int w)
        {
            edge[cnt].to=v;
            edge[cnt].cap=w;
            edge[cnt].flow=0;
            next[cnt]=head[u];
            head[u]=cnt++;
    
            edge[cnt].to=u;
            edge[cnt].flow=0;
            edge[cnt].cap=0;
            next[cnt]=head[v];
            head[v]=cnt++;
        }
    
        void init()
        {
            s=0;
            t=401;
            cnt=0;
            memset(head,-1,sizeof(head));
    
            for (int i=1;i<=100;i++) {
                addEdge(s,i,1);
            }
            for (int i=301;i<=400;i++) {
                addEdge(i,t,1);
            }
        }
    
        bool bfs()
        {
            memset(deep,0,sizeof(deep));
            memset(vis,0,sizeof(vis));
            queue<int> q;
            vis[s]=true;
            deep[s]=0;
            q.push(s);
            while (!q.empty()) {
                int u=q.front();
                q.pop();
                for (int i=head[u];i!=-1;i=next[i]) {
                    Edge &e=edge[i];
                    if (!vis[e.to]&&e.cap>e.flow) {
                        deep[e.to]=deep[u]+1;
                        vis[e.to]=true;
                        q.push(e.to);
                    }
                }
            }
            return vis[t];
        }
    
        int dfs(int u,int in)
        {
            if (u==t||in==0) {
                return in;
            }
            int out=0,f=0;
            for (int &i=cur[u];i!=-1;i=next[i]) {
                Edge &e=edge[i];
                if (deep[e.to]==deep[u]+1&&(f=dfs(e.to,min(e.cap-e.flow,in)))>0) {
                    in-=f;
                    out+=f;
                    edge[i].flow+=f;
                    edge[i^1].flow-=f;
                    if (in==0) {
                        break;
                    }
                }
            }
            return out;
        }
    
        int maxflow()
        {
            int ans=0;
            while (bfs()) {
                for (int i=0;i<4*maxn;i++) {
                    cur[i]=head[i];
                }
                ans+=dfs(s,INF);
            }
            return ans;
        }
    
        void print()
        {
            for (int i=0;i<=400;i++) {
                if (head[i]!=-1) {
                    printf("%d:",i);
                    for (int j=head[i];j!=-1;j=next[j]) {
                        printf("%d %d %d   ",edge[j].to,edge[j].cap,edge[j].flow);
                    }
                    printf("
    ");
                }
            }
        }
    
    }DC;
    
    int main()
    {
        int food,drink;
        scanf("%d%d%d",&n,&f,&d);
        DC.init();
        for (int i=1;i<=n;i++) {
            scanf("%d%d",&fi,&di);
            for (int j=0;j<fi;j++) {
                scanf("%d",&food);
                DC.addEdge(food,100+i,1);
            }
            DC.addEdge(100+i,200+i,1);
            for (int j=0;j<di;j++) {
                scanf("%d",&drink);
                DC.addEdge(i+200,drink+300,1);
            }
        }
        //DC.print();
        printf("%d
    ",DC.maxflow());
        return 0;
    }
    /*
    2 2 2
    1 1 2 1
    2 1 2 1 2
    */
    
    
  • 相关阅读:
    centos7安装supervisor
    redis4.0 cluster搭建
    网易cetus数据库中间件安装-读写分离版本
    mongodb副本集基于centos7部署
    C# 单例模式实现
    HttpWebRequest的GET和POST方法
    C#中$的用法
    判断一个表是否存在
    C# 继承的一些解释
    C# 虚方法和抽象方法
  • 原文地址:https://www.cnblogs.com/xyqxyq/p/12328887.html
Copyright © 2011-2022 走看看