• 网络流建图(典型)(EK)


    题目链接:https://cn.vjudge.net/contest/68128#problem/B

    具体思路:

    按照  源点 - > 食物 - > 牛1 - > 牛2 - > 饮料 的方式建图。 求最大流就相当于求最大匹配量。

    AC代码;

    #include<iostream>
    #include<string>
    #include<iomanip>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<stack>
    #include<stdio.h>
    #include<queue>
    using namespace std;
    # define maxn 2000+10
    # define inf 0x3f3f3f3f
    # define ll long long
    int Map[maxn][maxn];
    int vis[maxn];
    int pre[maxn];
    bool bfs(int st,int ed)
    {
        memset(vis,0,sizeof(vis));
        vis[st]=1;
        pre[st]=st;
        queue<int>q;
        q.push(st);
        while(!q.empty())
        {
            int top=q.front();
            q.pop();
            for(int i=1; i<=ed; i++)
            {
                if(Map[top][i]&&!vis[i])
                {
                    vis[i]=1;
                    pre[i]=top;
                    if(i==ed)return true;
                    q.push(i);
                }
            }
        }
        return false;
    }
    int EK(int st,int ed)
    {
        int ans=0;
        while(bfs(st,ed))
        {
            int minn=inf;
            for(int i=ed; i!=st; i=pre[i])
            {
                minn=min(minn,Map[pre[i]][i]);
            }
            for(int i=ed; i!=st; i=pre[i])
            {
                Map[pre[i]][i]-=minn;
                Map[i][pre[i]]+=minn;
            }
            ans+=minn;
        }
        return ans;
    }
    int main()
    {
        int n,f,d;
        while(~scanf("%d%d%d",&n,&f,&d))
        {
            memset(Map,0,sizeof(Map));
            int t1,t2,temp;
            int divn=n+f+d;
            int start=n+divn+1;
            int ed=start+1;
            for(int i=1; i<=n; i++)
            {
                scanf("%d%d",&t1,&t2);
                for(int j=1; j<=t1; j++)
                {
                    scanf("%d",&temp);
                    
                    Map[temp][f+d+i]=1;//食物到牛1
                }
                for(int j=1; j<=t2; j++)
                {
                    scanf("%d",&temp);
                    Map[divn+i][f+temp]=1;//牛2到饮料
                }
            }
            for(int i=1; i<=n; i++)
            {
                Map[f+d+i][divn+i]=1;//牛1与牛2 建立关系
            }
            for(int i=1; i<=f; i++)
            {
                Map[start][i]=1;//源点与牛1建立关系
            }
            for(int i=1; i<=d; i++)
            {
                Map[f+i][ed]=1;//饮料与汇点建立关系
            }
            int ans=EK(start,ed);
            printf("%d
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    Delphi中DLL初始化和退出处理
    03003_Http响应
    雷林鹏分享:CSS 属性 选择器
    雷林鹏分享:CSS 媒体类型
    雷林鹏分享:CSS 图像拼合技术
    雷林鹏分享:CSS 图像透明/不透明
    雷林鹏分享:CSS 图片廊
    雷林鹏分享:CSS 提示工具(Tooltip)
    雷林鹏分享:CSS 下拉菜单
    雷林鹏分享:CSS 导航栏
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10262849.html
Copyright © 2020-2023  润新知