• POJ 3281 Dining


    农夫为他的 N (1 ≤ N ≤ 100) 牛准备了 F (1 ≤ F ≤ 100)种食物和 D (1 ≤ D ≤ 100) 种饮料。每头牛都有各自喜欢的食物和饮料,而每种食物或饮料只能分配给一头牛。最多能有多少头牛可以同时得到喜欢的食物和饮料?

    Input

    第一行输入三个整数N, F, D
    接下来n行,每行先输入两个整数 Fi 和 Di,分别表示编号为 i 的牛喜欢的食物和饮料的数量,接下来的Fi个整数表示第i头牛喜欢的食物的编号,最后Di个整数表示第i头牛喜欢的饮料的编号。

    Output

    输出同时得到喜欢的食物和饮料的牛的数量的最大值。

    Sample Input

    4 3 3
    2 2 1 2 3 1
    2 2 2 3 1 2
    2 2 1 3 1 2
    2 1 1 3 3

    Sample Output

    3
    一开始建图我就建错了
    源点 牛 食物 饮料 汇点
    这样是不对的 因为这样让牛能喝的饮料数变多了
    应该是
    源点 食物 牛 牛 饮料 汇点
    牛和牛是同一头牛 ,因为这样可以保证牛的通过量只能为1 这就是所谓的拆点吧
    #include<iostream>
    #include<queue>
    #include<string.h>
    #include<stdio.h>
    #include<algorithm>
    using namespace std;
    const int maxn=500;
    const int inf=0x3f3f3f;
    int N;
    int depth[maxn];
    int a[maxn][maxn];
    bool bfs(int s,int e)
    {
        queue<int>q;
        memset(depth,-1,sizeof(depth));
        depth[s]=0;
        q.push(s);
        while(!q.empty())
        {
            int now=q.front();
            q.pop();
            for(int i=1;i<=N;i++)
            {
                if(depth[i]==-1&&a[now][i])
                {
                    depth[i]=depth[now]+1;
                    q.push(i);
                }
            }
        }
        return depth[e]>0;
     } 
     int dfs(int now,int e,int nowflow)
     {
         if(now==N) return nowflow;
         
         int findflow=0;
         for(int i=1;i<=N;i++)
         {
             if(a[now][i]&&depth[i]==depth[now]+1)
             {
                 findflow=dfs(i,e,min(nowflow,a[now][i]));
                 if(findflow)
                 {
                     a[now][i]-=findflow;
                     a[i][now]+=findflow;
                     return findflow;
                 }
             }
         }
         if(!findflow) depth[now]=-2;
         return false;
     }
     int dinic(int s,int e)
     {
         int maxflow=0;
         while(bfs(s,e))
         maxflow+=dfs(s,e,1<<20);
         
         return maxflow;
     }
     int main()
     {
         int n,f,d;
         while(scanf("%d%d%d",&n,&f,&d)!=EOF)
         {
             memset(a,0,sizeof(a));
             N=f+d+2*n+2;
             for(int i=1;i<=f;i++)
             a[1][i+1]=1;
             for(int i=1;i<=n;i++)
             a[i+f+1][i+f+1+n]=1;
             for(int i=1;i<=d;i++)
             a[i+1+f+2*n][2+f+2*n+d]=1;
             for(int i=1;i<=n;i++)
             {
                 int t1,t2,t3;
                 cin>>t1>>t2;
                 for(int j=1;j<=t1;j++)
                 {
                     cin>>t3;
                     a[t3+1][i+1+f]=1;
                 }
                 for(int j=1;j<=t2;j++)
                 {
                     cin>>t3;
                     a[i+1+f+n][t3+1+f+2*n]=1;
                 }
             }
             cout<<dinic(1,N)<<endl;
         }
     }
     
  • 相关阅读:
    自定义异常
    finally关键字
    捕捉异常try-catch
    throws抛出异常
    exception概述和分类
    jvm前奏篇
    Java并发编程学习随笔 (一) 使用run() 和 start()的差别
    MyCat学习 ------分库分表 随笔
    java最常用的内置工具类
    Mybatis框架常见面试题
  • 原文地址:https://www.cnblogs.com/wpbing/p/9512248.html
Copyright © 2020-2023  润新知