题意描述

New Years Party

\(N(3\leq N\leq 200)\) 头奶牛举办新年聚会。每头奶牛会做几种不同的佳肴(以“碟”记数)。

一共有 \(D(5\leq D\leq 100)\) 种菜肴,依次以 \(1\) 到 \(D\) 的数字标记。

大家希望聚会上的菜肴数量越多越好,但是同种菜肴的数量有一个上限。

每头奶牛可以带 \(K\) 碟菜肴 \((1\leq K\leq 5)\) ,但必须都是不同的菜肴。

求聚会上最多可能有多少碟菜肴?

算法分析

闲话

一开始以为是什么神仙 贪心 或 DP,结果撑死推不出 DP 柿子,又口胡不了贪心...。

经 dalao 点拨之后发现网络流模型是真的难看出来。

建图

建立一个超级源点连接 \(1\)~\(n\) 号节点(表示 \(1\)~\(n\) 号奶牛),边权为 \(k\)。

若 \(i\) 号奶牛会做 \(j\) 号菜,就连接 \(edge(i,j+n)\),边权为 \(1\)。

建立一个超级汇点连接 \(1+n\)~\(d+n\) 号节点(表示 \(1\)~\(d\) 号菜),边权为每种菜的数量上限。

网络流

然后就是 Dinic 的板子了(据说 EK 会 T)。

代码实现

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#define N 210
#define D 110
#define M 5000010
#define INF 0x3f3f3f3f
using namespace std; int n,kk,dd,s,t,head[N+D],cnt=1;
struct Edge{
int nxt,to,val;
}ed[M];
queue<int>q; int read(){
int x=0,f=1;char c=getchar();
while(c<'0' || c>'9') f=(c=='-')?-1:1,c=getchar();
while(c>='0' && c<='9') x=x*10+c-48,c=getchar();
return x*f;
} void add(int u,int v,int w){
ed[++cnt].nxt=head[u];
ed[cnt].to=v;
ed[cnt].val=w;
head[u]=cnt;
ed[++cnt].nxt=head[v];
ed[cnt].to=u;
ed[cnt].val=0;
head[v]=cnt;
return;
} int d[N+D]; bool bfs(){
memset(d,0,sizeof(d));
while(!q.empty()) q.pop();
q.push(s);d[s]=1;
while(!q.empty()){
int u=q.front();q.pop();
for(int i=head[u];i;i=ed[i].nxt){
int v=ed[i].to,w=ed[i].val;
if(w && !d[v]){
d[v]=d[u]+1;
if(v==t) return true;
q.push(v);
}
}
}
return false;
} int dinic(int u,int flow){
if(u==t) return flow;
int rest=flow;
for(int i=head[u];i && rest;i=ed[i].nxt){
int v=ed[i].to,w=ed[i].val;
if(w && d[v]==d[u]+1){
int k=dinic(v,min(rest,w));
if(!k) d[v]=0;
ed[i].val-=k;
ed[i^1].val+=k;
rest-=k;
}
}
return flow-rest;
} int main(){
//freopen("party.in","r",stdin);
//freopen("party.out","w",stdout);
n=read(),kk=read(),dd=read();
s=0,t=n+dd+1;
int a,b;
for(int i=1;i<=dd;i++)
a=read(),add(i+n,t,a);
for(int i=1;i<=n;i++){
a=read();
for(int j=1;j<=a;j++)
b=read(),add(i,b+n,1);
}
for(int i=1;i<=n;i++) add(s,i,kk);
int ans=0,flow;
while(bfs())
if(flow=dinic(s,INF)) ans+=flow;
printf("%d\n",ans);
//fclose(stdin);fclose(stdout);
return 0;
}

完结撒花。

【USACO】New Years Party的更多相关文章

  1. POJ 1986 Distance Queries / UESTC 256 Distance Queries / CJOJ 1129 【USACO】距离咨询(最近公共祖先)

    POJ 1986 Distance Queries / UESTC 256 Distance Queries / CJOJ 1129 [USACO]距离咨询(最近公共祖先) Description F ...

  2. 1642: 【USACO】Payback(还债)

    1642: [USACO]Payback(还债) 时间限制: 1 Sec 内存限制: 64 MB 提交: 190 解决: 95 [提交] [状态] [讨论版] [命题人:外部导入] 题目描述 &quo ...

  3. 1519: 【USACO】超级书架

    1519: [USACO]超级书架 时间限制: 1 Sec 内存限制: 64 MB 提交: 1735 解决: 891 [提交] [状态] [讨论版] [命题人:外部导入] 题目描述 Farmer Jo ...

  4. Java实现【USACO】1.1.2 贪婪的礼物送礼者 Greedy Gift Givers

    [USACO]1.1.2 贪婪的礼物送礼者 Greedy Gift Givers 题目描述 对于一群要互送礼物的朋友,你要确定每个人送出的礼物比收到的多多少(and vice versa for th ...

  5. 【CPLUSOJ】【USACO】【差分约束】排队(layout)

    [题目描述] Robin喜欢将他的奶牛们排成一队.假设他有N头奶牛,编号为1至N.这些奶牛按照编号大小排列,并且由于它们都很想早点吃饭,于是就很可能出现多头奶牛挤在同一位置的情况(也就是说,如果我们认 ...

  6. 【USACO】Dining

    [题目链接] [JZXX]点击打开链接 [caioj]点击打开链接 [算法] 拆点+网络流 [代码] #include<bits/stdc++.h> using namespace std ...

  7. 【USACO】Optimal Milking

    题目链接 :        [POJ]点击打开链接        [caioj]点击打开链接 算法 : 1:跑一遍弗洛伊德,求出点与点之间的最短路径 2:二分答案,二分”最大值最小“ 3.1:建边,将 ...

  8. 【USACO】 Balanced Photo

    [题目链接] 点击打开链接 [算法] 树状数组 [代码] #include<bits/stdc++.h> using namespace std; int i,N,ans,l1,l2; ] ...

  9. 【USACO】 Balanced Lineup

    [题目链接] 点击打开链接 [算法] 这是一道经典的最值查询(RMQ)问题. 我们首先想到线段树.但有没有更快的方法呢?对于这类问题,我们可以用ST表(稀疏表)算法求解. 稀疏表算法.其实也是一种动态 ...

  10. 【USACO】The Cow Prom

    [题目链接] 点击打开链接 [算法] tarjan求强连通分量 [代码] #include<bits/stdc++.h> #define MAXN 20005 using namespac ...

随机推荐

  1. unity inspector 自动装载Commont和Prefab属性

    在使用unity的过程中,经常遇到这样的问题:每次都需要手动为序列化属性拖拽赋值.像这样: 试着找了找,真的找到了一份代码,但是缺少自动装载Prefab的功能.之后我花了点时间添加这个功能. 使用方法 ...

  2. interp1一维数据插值在matlab中的用法

    转载:https://ww2.mathworks.cn/help/matlab/ref/interp1.html?s_tid=srchtitle#btwp6lt-2_1 interp1 一维数据插值( ...

  3. Visual C++中各种文件的作用(详细)

    参考:http://blog.sina.com.cn/s/blog_6975d67c0100r3kx.html DSW:全称是Developer Studio Workspace,最高级别的配置文件, ...

  4. Linux中的硬链接和软连接

    1.Linux链接概念Linux链接分两种,一种被称为硬链接(Hard Link),另一种被称为符号链接(Symbolic Link).默认情况下,ln命令产生硬链接. [硬连接]硬连接指通过索引节点 ...

  5. Object.assign()的使用

    一.Object.assign()对象的拷贝 1 Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象.它将返回目标对象. 2 Object.assign(ta ...

  6. Java之格林威治时间格式转换成北京时间格式

    Java之格林威治时间格式转换成北京时间格式 package com.mtons.mblog; import java.text.ParseException; import java.text.Si ...

  7. 一文搞懂PV、UV、VV、IP及其关系与计算

    写在前面 十一长假基本上过去了,很多小伙伴在假期当中还是保持着持续学习的心态,也有不少小伙伴在微信上问我,让我推送相关的文章.这个时候,我都是抽空来整理小伙伴们的问题,然后,按照顺序进行推文. PS: ...

  8. Hello World背后的事情

    Hello World是不少人学习C++的第一项内容,代码看似简单,很多东西却涉及根本 #include <iostream> using namespace std; int main( ...

  9. [tip:,x86/urgent] x86: Fix early boot crash on gcc-10, third try

    [tip:,x86/urgent] x86: Fix early boot crash on gcc-10, third try   https://lore.kernel.org/patchwork ...

  10. 例题3-3 回文词(Palindromes, UVa401)

    输入一个字符串,判断它是否为回文串以及镜像串.输入字符串保证不含数字0.所谓 回文串,就是反转以后和原串相同,如abba和madam.所有镜像串,就是左右镜像之后和原串相同,如2S和3AIAE.注意, ...