• C


    题目大意:N头牛,F个食物,D个饮料。每一个食物和饮料只能分享给一头牛,每一头牛也最多获得一个饮料和一个食物,问最多有几头牛可以同时获得一个食物和一个饮料?

    这是一个典型的最大流问题。难点在于建图,建完图就是最大流裸题了。

    关于见图。

    每头牛都有喜欢的食物和饮料,首先看对牛与食物和牛与饮料分别被建边。注意到饮料和食物是毫无关系的。食物是食物,饮料是饮料,并不能相互代替。因此我们见图的时候可以用食物指向牛,牛指向饮料(反过来也可以)。注意,每头牛最多获得一个食物和饮料,这时候就需要对顶点进行限流。即牛与牛之间要加一条边权为1的边。

    最终建成的图应该是这样的:

     边均为有向边,方向均指向右方。

    code:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    const int INF=1e9+7;
    const int N=1E4+7;
    struct stu{
        int to,val,nxt;
    }edge[N];
    int n,f,d;
    int dis[N];
    int head[N],tol=0;
    void add(int x,int y,int z){
        edge[tol].to=y;
        edge[tol].val=z;
        edge[tol].nxt=head[x];
        head[x]=tol++;
    } 
    bool bfs(int s,int t){
        for(int i=0;i<=n+n+f+d+1;i++) dis[i]=INF;
        queue<int>que;
        dis[s]=0;
        que.push(s);
        while(!que.empty()){
            int u=que.front();
            que.pop();
            for(int i=head[u];i!=-1;i=edge[i].nxt){
                int v=edge[i].to;
                int w=edge[i].val;
                if(w>0&&dis[u]+1<dis[v]) {
                    dis[v]=dis[u]+1;
                    que.push(v);
                }
            }
        }
        return dis[t]!=INF;
    }
    int dfs(int s,int t,int  mn){
        if(s==t) return mn;
        for(int i=head[s];i!=-1;i=edge[i].nxt){
            int v=edge[i].to;
            int w=edge[i].val;
            if(w<=0||dis[v]!=dis[s]+1) continue ;
            int cw=dfs(v,t,min(w,mn));
            if(cw>0){
                edge[i].val-=cw;
                edge[i^1].val+=cw;
                return cw;
            }
        }
        return 0;
    }
    void dicnic(int s,int t){
        int  ans=0;
        while(bfs(s,t)){
            int d;
            while((d=dfs(s,t,INF))!=0){
                ans+=d;
            }
        } 
        cout<<ans<<endl;
    }
    int main(){
        memset(head,-1,sizeof head);
        cin>>n>>f>>d;
        int s=0,t=n+n+f+d+1;//源点与汇点
    
        for(int i=1;i<=n;i++){//牛。
            int t1,t2,food,drink;
            cin>>t1>>t2;
            for(int j=1;j<=t1;j++){
                cin>>food;
                add(food+n+n,i,1);
                add(i,food+n+n,0);
            }
            for(int j=1;j<=t2;j++){
                cin>>drink; 
                add(i+n,drink+n+n+f,1);
                add(drink+n+n+f,i+n,0);
            }
        }
        for(int i=1;i<=n;i++){
            add(i,i+n,1);
            add(i+n,i,0);
        }
        for(int i=1;i<=f;i++){
            add(s,n+n+i,1);
            add(n+n+i,s,0);
        } 
        for(int i=1;i<=d;i++){
            add(n+n+f+i,t,1);
            add(t,n+n+f+i,0);
        }
        dicnic(s,t);
        return 0;
    }
  • 相关阅读:
    pycharm修改快捷键
    pycharm如何解决新建的文件没有后缀的问题
    创建py模板
    用ctrl+鼠标滚动调节字体大小
    pycharm调整代码长度分割线
    pycharm怎么设置代码自动补齐
    python3用BeautifulSoup抓取div标签
    python3用BeautifulSoup用re.compile来匹配需要抓取的href地址
    python3用BeautifulSoup用limit来获取指定数量的a标签
    python3用BeautifulSoup用字典的方法抓取a标签内的数据
  • 原文地址:https://www.cnblogs.com/Accepting/p/13372323.html
Copyright © 2020-2023  润新知