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;
    }
    
  • 相关阅读:
    flash中网页跳转总结
    as3自定义事件
    mouseChildren启示
    flash拖动条移出flash无法拖动
    需要一个策略文件,但在加载此媒体时未设置checkPolicyFile标志
    Teach Yourself SQL in 10 Minutes
    电子书本地转换软件 Calibre
    Teach Yourself SQL in 10 Minutes
    Teach Yourself SQL in 10 Minutes
    Teach Yourself SQL in 10 Minutes – Page 31 练习
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366485.html
Copyright © 2011-2022 走看看