题意描述

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. Python练习题 023:比后面的人大2岁

    [Python练习题 023] 有5个人坐在一起,问第五个人多少岁?他说比第4个人大2岁.问第4个人岁数,他说比第3个人大2岁.问第三个人,又说比第2人大两岁.问第2个人,说比第一个人大两岁.最后 问 ...

  2. 井字棋小游戏(C语言)

    最近沉迷于<NetHack>.<DCSS>等字符游戏,对其很感兴趣,于是用C语言写了个字符界面的井字棋小游戏.欢迎大家指教. 编写时遇到了一些问题,我原先准备用循环,直到读取到 ...

  3. 晶振(crystal)与谐振荡器(oscillator)

    参考: 1. https://wenku.baidu.com/view/e609af62f5335a8102d2202f.html 2. 晶体振荡器也分为无源晶振和有源晶振两种类型.无源晶振与有源晶振 ...

  4. 题解【QTree3】

    题目描述 给出N个点的一棵树(N-1条边),节点有白有黑,初始全为白 有两种操作: 0 i : 改变某点的颜色(原来是黑的变白,原来是白的变黑) 1 v : 询问1到v的路径上的第一个黑点,若无,输出 ...

  5. JVM系列【3】Class文件加载过程

    JVM系列笔记目录 虚拟机的基础概念 class文件结构 class文件加载过程 jvm内存模型 JVM常用指令 GC与调优 Class文件加载过程 JVM加载Class文件主要分3个过程:Loadi ...

  6. [学习笔记] 数位DP的dfs写法

    跟着洛谷日报走,算法习题全都有! 嗯,没错,这次我也是看了洛谷日报的第84期才学会这种算法的,也感谢Mathison大佬,素不相识,却写了一长篇文章来帮助我学习这个算法. 算法思路: 感觉dfs版的数 ...

  7. Redis 中 HyperLogLog 的使用场景

    什么是基数估算 HyperLogLog 是一种基数估算算法.所谓基数估算,就是估算在一批数据中,不重复元素的个数有多少. 从数学上来说,基数估计这个问题的详细描述是:对于一个数据流 {x1,x2,.. ...

  8. EV加密播放器的分析过程+过虚拟机方法

    开启了OD载入播放器进行分析,发现如下问题:1.播放器会进行翻录检测2.防止虚拟机播放3.视频播放后,可直接对内存操作提取出源视频翻录检测:主要是对指定的文件名或进程名对比虚拟机检测:是针对虚拟机特征 ...

  9. html学习(1)

    认识html标签 1.<h1></h1>就是标题标签,<p></p>是段落标签,img是图片标签.  2.html中的标签一般都是成对出现的,分开始标签 ...

  10. linux(centos8):安装jmeter5.3

    一,jmeter的用途: Apache JMeter是Apache组织开发的基于Java的压力测试工具.用于对软件做压力测试, 它最初被设计用于Web应用测试,但后来扩展到其他测试领域.  Apach ...