http://www.lydsy.com/JudgeOnline/problem.php?id=4873

最大权闭合子图。。。

建图:

1.d[i][j]:i->j区间的费用,d[i][j] > 0 ins(S,id(i,j),d[i][j]) 否则ins(id(i,j),T,-d[i][j]) 套路

2.对于寿司怎么搞,m=1,ins(种类,T,a[i]*a[i]),ins(寿司,种类,inf):必须割掉初始的费用,ins(寿司,T,a[i]),ins(区间,寿司, inf):每个区间割掉需要寿司的花费

3.ins(id(i,j),id(i+1,j),inf),ins(id(i,j),id(i,j-1),inf):选了大的区间的必须选小的区间

但是上面有一步可以改进,就是2的最后。因为选了大的一定会选小的,那么我们只用将[i,i]这个区间向寿司连边就行了。

记住a[i]有1000,并且汇点不要取太小。。。

#include<bits/stdc++.h>
using namespace std;
const int N = , inf = << ;
struct edge {
int nxt, to, f;
} e[N * ];
int dis[N], used[N], head[N], q[N], iter[N], d[][], a[N];
int n, m, sum, T = , num = , cnt = ;
namespace maxflow
{
void link(int u, int v, int f)
{
e[++cnt].nxt = head[u];
head[u] = cnt;
e[cnt].to = v;
e[cnt].f = f;
}
void ins(int u, int v, int f)
{
link(u, v, f); link(v, u, );
}
bool bfs()
{
int l = , r = ; q[++r] = ;
memset(dis, , sizeof(dis)); dis[] = ;
while(l <= r)
{
int u = q[l++];
for(int i = head[u]; i; i = e[i].nxt) if(!dis[e[i].to] && e[i].f)
{
dis[e[i].to] = dis[u] + ;
q[++r] = e[i].to;
}
}
return dis[T] > ;
}
int dfs(int u, int delta)
{
if(u == T) return delta;
int ret = ;
for(int &i = iter[u]; i && delta; i = e[i].nxt) if(e[i].f && dis[e[i].to] == dis[u] + )
{
int x = dfs(e[i].to, min(delta, e[i].f));
e[i].f -= x; e[i ^ ].f += x;
ret += x; delta -= x;
}
return ret;
}
int id(int i, int j) { return (i - ) * n + j; }
void build()
{
//每个编号和T连边,每个寿司和对应编号连边
int D = n * n;
T = N - ;
for(int i = ; i <= n; ++i)
{ // i + D:寿司 a[i] + 2 * D: 种类 id(i, i): 区间
ins(i + D, T, a[i]); //每个寿司
if(d[i][i] < ) ins(id(i, i), T, -d[i][i]);
else ins(, id(i, i), d[i][i]);
ins(id(i, i), i + D, inf);
if(!m) continue;
if(!used[a[i]])
{
used[a[i]] = ;
ins(a[i] + * D, T, a[i] * a[i]);
}
ins(i + D, a[i] + * D, inf);
}
for(int i = ; i <= n; ++i)
for(int j = i + ; j <= n; ++j)
{
if(d[i][j] < ) ins(id(i, j), T, -d[i][j]);
else ins(, id(i, j), d[i][j]);
if(i < n) ins(id(i, j), id(i + , j), inf);
if(j > ) ins(id(i, j), id(i, j - ), inf);
}
}
int dinic()
{
int ret = ;
while(bfs())
{
for(int i = ; i <= T; ++i) iter[i] = head[i];
ret += dfs(, inf);
}
return ret;
}
} using namespace maxflow;
int main()
{
scanf("%d%d", &n, &m);
for(int i = ; i <= n; ++i) scanf("%d", &a[i]);
for(int i = ; i <= n; ++i)
for(int j = i; j <= n; ++j)
{
scanf("%d", &d[i][j]);
if(d[i][j] > ) sum += d[i][j];
}
build();
sum -= dinic();
printf("%d\n", sum);
return ;
}

bzoj4873的更多相关文章

  1. 【BZOJ4873】[六省联考2017]寿司餐厅(网络流)

    [BZOJ4873][六省联考2017]寿司餐厅(网络流) 题面 BZOJ 洛谷 题解 很有意思的题目 首先看到答案的计算方法,就很明显的感觉到是一个最大权闭合子图. 然后只需要考虑怎么构图就行了. ...

  2. 【BZOJ4873】[Shoi2017]寿司餐厅 最大权闭合图

    [BZOJ4873][Shoi2017]寿司餐厅 Description Kiana最近喜欢到一家非常美味的寿司餐厅用餐.每天晚上,这家餐厅都会按顺序提供n种寿司,第i种寿司有一个代号ai和美味度di ...

  3. BZOJ4873 Shoi2017寿司餐厅(最小割)

    选择了某个区间就必须选择其所有子区间,容易想到这是一个最大权闭合子图的模型.考虑将区间按长度分层,相邻层按包含关系连边,区间[i,j]的权值即di,j,其中最后一层表示长度为1的区间的同时也表示寿司本 ...

  4. BZOJ4873 [Shoi2017]寿司餐厅 【最大权闭合子图】

    题目链接 BZOJ4873 题解 题意很鬼畜,就可以考虑网络流[雾] 然后就会发现这是一个裸的最大权闭合子图 就是注意要离散化一下代号 #include<algorithm> #inclu ...

  5. 【最大权闭合子图】bzoj4873 [Shoi2017]寿司餐厅

    4873: [Shoi2017]寿司餐厅 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 369  Solved: 256[Submit][Status ...

  6. [bzoj4873]寿司餐厅

    来自FallDream的博客,未经允许,请勿转载,谢谢. Kiana最近喜欢到一家非常美味的寿司餐厅用餐.每天晚上,这家餐厅都会按顺序提供n种寿司,第i种寿司有一个代号ai和美味度di,i,不同种类的 ...

  7. BZOJ4873[Shoi2017]寿司餐厅——最大权闭合子图

    题目描述 Kiana最近喜欢到一家非常美味的寿司餐厅用餐.每天晚上,这家餐厅都会按顺序提供n种寿司,第i种寿司有一个 代号ai和美味度di,i,不同种类的寿司有可能使用相同的代号.每种寿司的份数都是无 ...

  8. bzoj4873(最大权闭合子图)

    今天学了最大权闭合子图..然后找了这道题,发现完全不会..... 看了题解发现这种有诸如选了一个就一定要选另外的一些的限制又要求最优值的题有的可以转化成最大权闭合子图, 这个题我们首先想到不会选相交的 ...

  9. bzoj千题计划265:bzoj4873: [六省联考2017]寿司餐厅

    http://www.lydsy.com/JudgeOnline/problem.php?id=4873 选a必选b,a依赖于b 最大权闭合子图模型 构图: 1.源点 向 正美味度区间 连 流量为 美 ...

  10. bzoj4873 [Shoi2017]寿司餐厅

    Input 第一行包含两个正整数n,m,分别表示这家餐厅提供的寿司总数和计算寿司价格中使用的常数. 第二行包含n个正整数,其中第k个数ak表示第k份寿司的代号. 接下来n行,第i行包含n-i+1个整数 ...

随机推荐

  1. python 网络编程基础

    1. 内容回顾补充 [] [^] 带有特殊意义的元字符到字符组内大部分都会取消它的特殊意义. 会取消的: [()+*.] -[(-)] -的位置决定了它的意义,写在字符组的第一个位置/最后一个位置就表 ...

  2. this关键字的由来及使用

    Student.java /* * 学生类 * * 起名字我们要求做到见名知意. * * 如果有局部变量名和成员变量名相同,在局部使用的时候,采用的是就近原则. * *我们有没有办法吧局部变量的nam ...

  3. Windows学习总结(11)——Windows批处理命令编写代码及小程序简介

    批处理(Batch)也称为批处理脚本.顾名思义,就是对某对象进行批量的处理.DOS批处理是基于DOS命令,用来自动地批量地执行DOS命令以实现特定操作的脚本.批处理是一种简化的脚本语言,它应用于DOS ...

  4. 【BZOJ4591】超能粒子炮·改(Lucas定理,组合计数)

    题意: 曾经发明了脑洞治疗仪&超能粒子炮的发明家SHTSC又公开了他的新发明:超能粒子炮·改--一种可以发射威力更加 强大的粒子流的神秘装置.超能粒子炮·改相比超能粒子炮,在威力上有了本质的提 ...

  5. Redis 配置【十】

    参考:http://www.runoob.com/redis/redis-conf.html Redis 的配置文件位于 Redis 安装目录下,文件名为 redis.conf. 你可以通过 CONF ...

  6. Linux下汇编语言学习笔记4 ---

    这是17年暑假学习Linux汇编语言的笔记记录,参考书目为清华大学出版社 Jeff Duntemann著 梁晓辉译<汇编语言基于Linux环境>的书,喜欢看原版书的同学可以看<Ass ...

  7. Linux下汇编语言学习笔记60 ---

    这是17年暑假学习Linux汇编语言的笔记记录,参考书目为清华大学出版社 Jeff Duntemann著 梁晓辉译<汇编语言基于Linux环境>的书,喜欢看原版书的同学可以看<Ass ...

  8. Linux下汇编语言学习笔记36 ---

    这是17年暑假学习Linux汇编语言的笔记记录,参考书目为清华大学出版社 Jeff Duntemann著 梁晓辉译<汇编语言基于Linux环境>的书,喜欢看原版书的同学可以看<Ass ...

  9. POJ——T 2976 Dropping tests

    http://poj.org/problem?id=2976 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13861   ...

  10. Search Insert Position(二分查找)

    Given a sorted array and a target value, return the index if the target is found. If not, return the ...