POJ3281Dining[最大流]

Dining

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 16352   Accepted: 7307

Description

Cows are such finicky eaters. Each cow has a preference for certain foods and drinks, and she will consume no others.

Farmer John has cooked fabulous meals for his cows, but he forgot to check his menu against their preferences. Although he might not be able to stuff everybody, he wants to give a complete meal of both food and drink to as many cows as possible.

Farmer John has cooked F (1 ≤ F ≤ 100) types of foods and prepared D (1 ≤ D ≤ 100) types of drinks. Each of his N (1 ≤ N ≤ 100) cows has decided whether she is willing to eat a particular food or drink a particular drink. Farmer John must assign a food type and a drink type to each cow to maximize the number of cows who get both.

Each dish or drink can only be consumed by one cow (i.e., once food type 2 is assigned to a cow, no other cow can be assigned food type 2).

Input

Line 1: Three space-separated integers: NF, and D 
Lines 2..N+1: Each line i starts with a two integers Fi and Di, the number of dishes that cow i likes and the number of drinks that cow i likes. The next Fi integers denote the dishes that cow i will eat, and the Di integers following that denote the drinks that cow i will drink.

Output

Line 1: A single integer that is the maximum number of cows that can be fed both food and drink that conform to their wishes

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

Hint

One way to satisfy three cows is: 
Cow 1: no meal 
Cow 2: Food #2, Drink #2 
Cow 3: Food #1, Drink #1 
Cow 4: Food #3, Drink #3 
The pigeon-hole principle tells us we can do no better since there are only three kinds of food or drink. Other test data sets are more challenging, of course.

Source

USACO 2007 Open Gold


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=105,INF=1e9;
int read(){
    char c=getchar();int x=0,f=1;
    while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1; c=getchar();}
    while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘; c=getchar();}
    return x*f;
}
int n,F,D,s,t,fi,di,v;
struct edge{
    int v,ne,c,f;
}e[N*N*3];
int h[N*4],cnt=0;
inline void ins(int u,int v,int c){
    cnt++;
    e[cnt].v=v;e[cnt].c=c;e[cnt].f=0;e[cnt].ne=h[u];h[u]=cnt;
    cnt++;
    e[cnt].v=u;e[cnt].c=0;e[cnt].f=0;e[cnt].ne=h[v];h[v]=cnt;
}

int cur[N*4];
int vis[N*4],d[N*4],q[N*4],head,tail;
bool bfs(){
    memset(vis,0,sizeof(vis));
    memset(d,0,sizeof(d));
    head=tail=1;
    q[tail++]=s;d[s]=0;vis[s]=1;
    while(head!=tail){
        int u=q[head++];
        for(int i=h[u];i;i=e[i].ne){
            int v=e[i].v;
            if(!vis[v]&&e[i].f<e[i].c){
                q[tail++]=v;vis[v]=1;
                d[v]=d[u]+1;
                if(v==t) return 1;
            }
        }
    }
    return 0;
}
int dfs(int u,int a){
    if(u==t||a==0) return a;
    int flow=0,f;
    for(int &i=cur[u];i;i=e[i].ne){
        int v=e[i].v;
        if(d[v]==d[u]+1&&(f=dfs(v,min(a,e[i].c-e[i].f)))>0){
            flow+=f;
            e[i].f+=f;
            e[((i-1)^1)+1].f-=f;
            a-=f;
            if(a==0) break;
        }
    }
    return flow;
}
int dinic(){
    int flow=0;
    while(bfs()){
        for(int i=s;i<=t;i++) cur[i]=h[i];
        flow+=dfs(s,INF);
    }
    return flow;
}
int main(){
    n=read();F=read();D=read(); s=0;t=F+n+n+D+1;
    for(int i=1;i<=F;i++) ins(s,i,1);
    for(int i=1;i<=D;i++) ins(F+n+n+i,t,1);
    for(int i=1;i<=n;i++){
        ins(F+i,F+n+i,1);
        fi=read();di=read();
        while(fi--){v=read();ins(v,F+i,1);}
        while(di--){v=read();ins(F+n+i,F+n+n+v,1);}
    }
    printf("%d",dinic());
}
时间: 2024-12-20 12:08:28

POJ3281Dining[最大流]的相关文章

【网络流最大流】poj3281Dining

/* EK算法版本的,比较慢哦.....详见下面dinic版本 ----------------------------------------- 题目是网络流最大流的问题 ---------------------------------------- 建图: 关键:拆点 把每个牛拆成两个点,牛作为一个点有流量限制,即每一头牛只能的一份饭. 把牛拆开后,将边的权值赋值为1, ---------------------------------------- 建好图后就可以EK算法最大流了 ---

poj3281-Dining ,最大流,建图

点击打开链接 分析: 求最大流 建图: 拆点 牛拆成左边与食物相连的左牛 和 右边与饮料相连的右牛 1.s->食物 连边 2.食物->左牛 3.左牛->右牛 4.右牛->饮料 5.饮料->t 边的方向为 s->食物->左牛->右牛->饮料->t #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #i

对IO流的操作(文件大小,拷贝,移动,删除)

import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;import java.io.SequenceInputStream; class LjyFileClass { /*LjyFileClass工具类使用需知: * * 1.计算

hdu3461Marriage Match IV 最短路+最大流

//给一个图.给定起点和终点,仅仅能走图上的最短路 //问最多有多少种走的方法.每条路仅仅能走一次 //仅仅要将在最短路上的全部边的权值改为1.求一个最大流即可 #include<cstdio> #include<cstring> #include<iostream> #include<queue> #include<vector> using namespace std ; const int inf = 0x3f3f3f3f ; const

Java学习之IO流三

1.从键盘接收两个文件夹路径,把其中一个文件夹中(包含内容)拷贝到另一个文件夹中(高效流) 1 /** 2 * 1.从键盘接收两个文件夹路径,把其中一个文件夹中(包含内容)拷贝到另一个文件夹中 3 * @author vanguard 4 * 5 */ 6 public class Demo01 { 7 public static void main(String[] args) { 8 //键盘输入两个文件夹路径 9 Scanner sc = new Scanner(System.in); 1

标准文档流

标准流指的是在不使用其他的与排列和定位相关的特殊CSS规则时,各种元素的排列规则.HTML文档中的元素可以分为两大类:行内元素和块级元素.       1.行内元素不占据单独的空间,依附于块级元素,行内元素没有自己的区域.它同样是DOM树中的一个节点,在这一点上行内元素和块级元素是没有区别的.       2.块级元素总是以块的形式表现出来,并且跟同级的兄弟块依次竖直排列,左右自动伸展,直到包含它的元素的边界,在水平方向不能并排.盒子在标准流中的定位原则margin控制的是盒子与盒子之间的距离,

Properties-转换流-打印流-序列化和反序列化-Commons-IO工具类

一.Properties 类(java.util)     概述:Properties 是一个双列集合;Properties 属于map的特殊的孙子类;Properties 类没有泛型,properties集合的key和value都是固定的数据类型(String),该集合提供了一些特有的方法存取值,是唯一一个可以与IO流相结合的集合; 定义:public class Properties extends Hashtable

14. 流、文件和IO

前言 InputStream/OutStream流用来处理设备之间的数据传输 Java.io 包几乎包含了所有操作输入.输出需要的类.所有这些流类代表了输入源和输出目标. Java.io 包中的流支持很多种格式,比如:基本类型.对象.本地化字符集等等. 一个流可以理解为一个数据的序列.输入流表示从一个源读取数据,输出流表示向一个目标写数据. 流按操作数据分为两种:字节流与字符流 按流向分为:输入流(InputStream)和输出流(OutputStream) Java 为 I/O 提供了强大的而

videojs集成--播放rtmp流

之前说到已经把流推送过来了,这时候就可以使用videojs来进行显示播放. 首先要先有一个文件,那就是video-js.swf 因为,这种播放方式html已经不能很好的进行播放了,需要用到flash来播放,videojs在这个地方就用到了这个. 代码就是下面这样. 里面一些细节注释都有. 重点就是看<video>标签里面的内容 [html] view plain copy <!DOCTYPE html> <html lang="en"> <he