zoukankan      html  css  js  c++  java
  • POJ3281——Dining(最大流)

    传送门

    很简单的一个网络流

    为了保证所有的食物和饮料都和牛连上

    把牛放在中间

    为了保证所有的牛都只被算一次

    每个牛作两个点,中间连一条容量为1的边

    跑最大流就可以了

    #include<iostream>
    #include<algorithm>
    #include<stdio.h>
    #include<queue>
    #include<cstdlib>
    #include<cstring>
    #include<string.h>
    #include<cmath>
    #include<math.h>
    using namespace std;
    int adj[100005],nxt[100005],to[100005],cap[100050],lev[100005],n,str,des,cnt=1,f,d;
    inline int read(){
        char ch=getchar();
        int res=0;
        while(!isdigit(ch)) ch=getchar();
        while(isdigit(ch)) res=(res<<1)+(res<<3)+(ch^48),ch=getchar();
        return res;
    }
    inline void addedge(int u,int v,int w)
    {
        nxt[++cnt]=adj[u],adj[u]=cnt,to[cnt]=v,cap[cnt]=w;
        nxt[++cnt]=adj[v];adj[v]=cnt,to[cnt]=u,cap[cnt]=0;
    } 
    inline bool bfs(){
        queue<int>q;int v;
        memset(lev,-1,sizeof(lev));
        q.push(str),lev[str]=0;
        while(!q.empty())
        {
            int u=q.front();q.pop();
            for(int e=adj[u];e;e=nxt[e])
            {
                if(cap[e]>0&&lev[v=to[e]]==-1)
                {
                    lev[v]=lev[u]+1,q.push(v);
                    if(v==des)    return true;
                }
            }
        }
        return false;
    }
    inline int dfs(int u,int flow)
    {
        if(u==des)return flow;
        int res=0,v,flw;
        for(int e=adj[u];e;e=nxt[e])
        {
            if(cap[e]>0&&lev[u]<lev[v=to[e]])
            {
                flw=dfs(v,min(cap[e],flow-res));
                if(flw==0) lev[v]=-1;
                cap[e]-=flw,cap[e^1]+=flw;
                res+=flw;if(res==flow) break;
            }
        }
        return res;
    }
    inline int dinic(){
        int ans=0;
        while(bfs())ans+=dfs(str,1<<30);
        return ans;
    }
    int main(){
        n=read(),f=read(),d=read();
        for(int i=1;i<=f;i++)
        addedge(1,i+1,1);
        int dr,fo;
        str=1,des=1+f+2*n+d+1;
        for(int i=1;i<=n;i++)
        {
            fo=read(),dr=read();
            for(int j=1;j<=fo;j++)
            {
                int fd=read();
                addedge(fd+1,f+1+i,1);
            }
            for(int j=1;j<=dr;j++)
            {
                int dk=read();
                addedge(f+n+1+i,2*n+f+1+dk,1);
            }
        }
        for(int i=f+1+1;i<=f+1+n;i++)
        {
            addedge(i,i+n,1);
        }
        for(int i=f+2*n+1+1;i<=2*n+f+1+d;i++)
        {
            addedge(i,des,1);
        }
        cout<<dinic()<<endl;
        return 0;
    }
    
  • 相关阅读:
    Windows系统的DOS常用命令
    常用pom
    ssm整合
    pom依赖集合
    json
    软件项目管理笔记-软件项目计划
    CSS
    网络配置
    用户组
    用户管理
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366485.html
Copyright © 2011-2022 走看看