题解

这道题的费用流如果朴素一点怎么建边呢

建出\(\sum_{i = 1}^{n} p^{i} M\)个点,第\(i\)个厨师的第\(j\)个点表示这个厨师倒数第\(j\)个做的是某道菜

这个点向汇点流一条流量为1,费用为0的边

然后每个菜建出来一个点,源点向每个菜流容量为\(p\),费用为0的点,第\(k\)个菜想第\(i\)个厨师的第\(j\)个点连 \(j * a[k][i]\)的边

比较好理解,因为最后一个菜的时间会被加一遍,倒数第二个菜会加两遍

但是这样会超时……我们尝试动态开点

我们初始化的时候只把所有厨师的倒数第一个菜建出来

由于我们有spfa跑最小费用最大流的时候,一定走了某个厨师的某个点,把这个厨师的下一道菜建出来就好了

代码

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#define enter putchar('\n')
#define space putchar(' ')
//#define ivorysi
using namespace std;
typedef long long int64;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {putchar('-');x = -x;}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
const int MOD = 1000000007; int N,M;
int a[45][105],p[45];
struct node {
int to,next,val,cap;
}E[2000005];
int head[40005],sumE = 1,Ncnt;
int S,T;
queue<int> Q;
bool inq[40005];
int dis[40005],pre[40005],dish[45],id[40005],chef[105],rk[105];
void add(int u,int v,int c,int a) {
E[++sumE].to = v;E[sumE].next = head[u];E[sumE].cap = c;E[sumE].val = a;
head[u] = sumE;
}
void addtwo(int u,int v,int c,int a) {
add(u,v,c,a);add(v,u,0,-a);
}
bool spfa() {
for(int i = 1 ; i <= Ncnt ; ++i) dis[i] = 0x7fffffff,pre[i] = 0;
dis[S] = 0;Q.push(S);
while(!Q.empty()) {
int u = Q.front();Q.pop();
inq[u] = 0;
for(int i = head[u] ; i ; i = E[i].next) {
if(E[i].cap) {
int v = E[i].to;
if(dis[v] > dis[u] + E[i].val) {
dis[v] = dis[u] + E[i].val;pre[v] = i;
if(!inq[v]) {inq[v] = 1;Q.push(v);}
}
}
}
}
return dis[T] < 0x7fffffff;
}
void Init() {
read(N);read(M);
S = ++Ncnt;T = ++Ncnt;
for(int i = 1 ; i <= N ; ++i) {
read(p[i]);dish[i] = ++Ncnt;
addtwo(S,dish[i],p[i],0);
}
for(int i = 1 ; i <= M ; ++i) {
id[++Ncnt] = i;
chef[i] = Ncnt;
rk[i] = 1;
}
for(int i = 1 ; i <= N ; ++i) {
for(int j = 1 ; j <= M ; ++j) {
read(a[i][j]);
addtwo(dish[i],chef[j],1,a[i][j]);
}
}
for(int i = 1 ; i <= M ; ++i) addtwo(chef[i],T,1,0);
}
void Solve() {
int ans = 0;
while(spfa()) {
int flow = 0x7fffffff;
for(int p = T,i = pre[p] ; i ; p = E[i ^ 1].to,i = pre[p]) {
flow = min(E[i].cap,flow);
}
for(int p = T,i = pre[p] ; i ; p = E[i ^ 1].to,i = pre[p]) {
E[i].cap -= flow;
E[i ^ 1].cap += flow;
}
ans += flow * dis[T];
int t = id[E[pre[T] ^ 1].to];chef[t] = ++Ncnt;++rk[t];id[chef[t]] = t;
for(int i = 1 ; i <= N ; ++i) {
addtwo(dish[i],chef[t],1,rk[t] * a[i][t]);
}
addtwo(chef[t],T,1,0);
}
out(ans);enter;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Init();
Solve();
}

【LOJ】#2674. 「NOI2012」美食节的更多相关文章

  1. @loj - 2674@ 「NOI2012」美食节

    目录 @description@ @solution@ @accepted code@ @details@ @description@ CZ 市为了欢迎全国各地的同学,特地举办了一场盛大的美食节. 作 ...

  2. Loj #2192. 「SHOI2014」概率充电器

    Loj #2192. 「SHOI2014」概率充电器 题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...

  3. Loj #3096. 「SNOI2019」数论

    Loj #3096. 「SNOI2019」数论 题目描述 给出正整数 \(P, Q, T\),大小为 \(n\) 的整数集 \(A\) 和大小为 \(m\) 的整数集 \(B\),请你求出: \[ \ ...

  4. Loj #3093. 「BJOI2019」光线

    Loj #3093. 「BJOI2019」光线 题目描述 当一束光打到一层玻璃上时,有一定比例的光会穿过这层玻璃,一定比例的光会被反射回去,剩下的光被玻璃吸收. 设对于任意 \(x\),有 \(x\t ...

  5. Loj #3089. 「BJOI2019」奥术神杖

    Loj #3089. 「BJOI2019」奥术神杖 题目描述 Bezorath 大陆抵抗地灾军团入侵的战争进入了僵持的阶段,世世代代生活在 Bezorath 这片大陆的精灵们开始寻找远古时代诸神遗留的 ...

  6. Loj #2542. 「PKUWC2018」随机游走

    Loj #2542. 「PKUWC2018」随机游走 题目描述 给定一棵 \(n\) 个结点的树,你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 \(Q\) 次询问,每次 ...

  7. Loj #3059. 「HNOI2019」序列

    Loj #3059. 「HNOI2019」序列 给定一个长度为 \(n\) 的序列 \(A_1, \ldots , A_n\),以及 \(m\) 个操作,每个操作将一个 \(A_i\) 修改为 \(k ...

  8. Loj #3056. 「HNOI2019」多边形

    Loj #3056. 「HNOI2019」多边形 小 R 与小 W 在玩游戏. 他们有一个边数为 \(n\) 的凸多边形,其顶点沿逆时针方向标号依次为 \(1,2,3, \ldots , n\).最开 ...

  9. Loj #3055. 「HNOI2019」JOJO

    Loj #3055. 「HNOI2019」JOJO JOJO 的奇幻冒险是一部非常火的漫画.漫画中的男主角经常喜欢连续喊很多的「欧拉」或者「木大」. 为了防止字太多挡住漫画内容,现在打算在新的漫画中用 ...

随机推荐

  1. python---堡垒机开发

    一:堡垒机需求分析 注意: 虽然我们在中间使用防火墙服务器对流量进行拦截和转发也可以起到过滤作用,但是我们无法去获取到完整,正确的操作记录.因为无论是客户端还是服务器端(管理员可能会去修改记录,而且可 ...

  2. Linux之find查找命令

    Linux中find常见用法示例 [root@localhost ~]# find  [PATH]  [option]  [action] 参数: 1. 与时间有关的参数:共有-atime.-ctim ...

  3. bzoj千题计划130:bzoj1305: [CQOI2009]dance跳舞

    http://www.lydsy.com/JudgeOnline/problem.php?id=1305 每个人拆为喜欢(yes)和不喜欢(no)两个点 二分答案 1.每两个人之间只能跳一次 喜欢则 ...

  4. 2015/11/6用Python写游戏,pygame入门(6):控制大量的对象

    昨天我们已经实现了这个游戏的三个基本类. 但是现在它还是没办法做成一个适合玩的游戏,毕竟只有一架敌机的游戏是很乏味的.所以,我们需要好多子弹,也需要好多敌机. 所以,我们要创建list,这个list存 ...

  5. XML学习(1)

    什么是XML? XML是可拓展标记语言,类似HTML,它的设计宗旨是为了传输数据,而不是像HTML那样显示数据.XML标签没有被预定义,需要用户自定义标签. xml文档必须包含根元素,它是其他所有元素 ...

  6. 使用反射代替不断添加的if-else来实现代码的可扩展性

    在调用一个自定义的GeneralHandler类里面的一个方法,该方法是针对数据库的一张表的所有操作(CRUD),根据传入的DealType来判断做那种操作 代码: using System;usin ...

  7. HDU 3535 AreYouBusy (混合背包之分组背包)

    题目链接 Problem Description Happy New Term! As having become a junior, xiaoA recognizes that there is n ...

  8. 【蓝桥杯单片机11】单总线温度传感器DS18B20的基本操作

    [蓝桥杯单片机11]单总线温度传感器DS18B20的基本操作 广东职业技术学院 欧浩源 单总线数字温度传感器DS18B20几乎成了各类单片机甚至ARM实验板的标配模块来,在蓝桥杯的往届省赛和国赛中,这 ...

  9. php的几个面试题

    1. mysql_num_fields() 返回结果集中字段的数目 如: $result = mysql_query("SELECT id,name,age FROM mydb.tb1 wh ...

  10. torch.nn.CrossEntropyLoss

    class torch.nn.CrossEntropyLoss(weight=None, size_average=True, ignore_index=-100, reduce=True) 我这里没 ...