【BZOJ4873】[Shoi2017]寿司餐厅 最大权闭合图
【BZOJ4873】[Shoi2017]寿司餐厅
Description
Input
Output
输出共一行包含一个正整数,表示Kiana能获得的总美味度减去花费的总钱数的最大值。
Sample Input
2 3 2
5 -10 15
-10 15
15
Sample Output
在这组样例中,餐厅一共提供了3份寿司,它们的代号依次为a1=2,a2=3,a3=2,计算价格时的常数m=1。在保证每次取寿司都能获得新的美味度的前提下,Kiana一共有14种不同的吃寿司方案:
1.Kiana一个寿司也不吃,这样她获得的总美味度和花费的总钱数都是0,两者相减也是0;
2.Kiana只取1次寿司,且只取第1个寿司,即她取寿司的情况为{[1,1]},这样获得的总美味度为5,花费的总钱数为1-2^2+1*2=6,两者相减为-1;
3.Kiana只取1次寿司,且只取第2个寿司,即她取寿司的情况为{[2,2]},这样获得的总美味度为-10,花费的总钱数为1-3^2+1*3=12,两者相减为-22;
4.Kiana只取1次寿司,且只取第3个寿司,即她取寿司的情况为{[3,3]},这样获得的总美味度为15,花费的总钱数为1*2^2+1*2=6,两者相减为9;
5.Kiana只取1次寿司,且取第1,2个寿司,即她取寿司的情况为{[1,2]},这样获得的总美味度为5+(-10)+(-10)=-1
5,花费的总钱数为(1-2^2+1*2)+(1-3^2+1*3)=18,两者相减为-33;
6.Kiana只取1次寿司,且取第2,3个寿司,即她取寿司的情况为{[2,3]},这样获得的总美味度为(-10)+15+15=20,花费的总钱数为(1-2^2+1*2)+(1*3^2+1*3)=18,两者相减为2;
7.Kiana只取1次寿司,且取第1,2,3个寿司,即她取寿司的情况为{[1,3]},这样获得的总美味度为5+(-10)+15+(-10)+15+15=30,花费的总钱数为(1*2^2+2*2)+(1*3^2+1*3)=20,两者相减为10。
8.Kiana取2次寿司,第一次取第1个寿司,第二次取第2个寿司,即她取寿司的情况为{[1,1],[2,2]},这样获得的总美味度为5+(-10)=-5,花费的总钱数为(1*2^2+1*2)+(1*3^2+1*3)=18,两者相减为-23;
9.Kiana取2次寿司,第一次取第1个寿司,第二次取第3个寿司,即她取寿司的情况为{[1,1],[3,3]},这样获得的总美味度为5+15=20,花费的总钱数为1*2^2+2*2=8,两者相减为12;
10.Kiana取2次寿司,第一次取第2个寿司,第二次取第3个寿司,即她取寿司的情况为{[2,2],[3,3]},这样获得的总美味度为(-10)+15=5,花费的总钱数为(1*2^2+1*2)+(1*3^2+1*3)=18,两者相减为-13;
11.Kiana取2次寿司,第一次取第1,2个寿司,第二次取第3个寿司,即她取寿司的情况为{[1,2],[3,3]},这样获得的总美味度为5+(-10)+(-10)+15=0,花费的总钱数为(1*2^2+2*2)+(1*3^2+1*3)=20,两者相减为-20;
12.Kiana取2次寿司,第一次取第1个寿司,第二次取第2,3个寿司,即她取寿司的情况为{[1,1],[2,3]},这样获得的总美味度为5+(-10)+15+15=25,花费的总钱数为(1-22+2-2)+(1-32+1-3)=20,两者相减为5;
13.Kiana取2次寿司,第一次取第1,2个寿司,第二次取第2,3个寿司,即她取寿司的情况为{[1,2],[2,3]},这样获得的总美味度为5+(-10)+15+(-10)+15=15,花费的总钱数为(1*2^2+2*2)+(1*3^2+1*3)=20,两者相减为-5;
14.Kiana取3次寿司,第一次取第1个寿司,第二次取第2个寿司,第三次取第3个寿司,即她取寿司的情况为{[1,1],[2,2],[3,3]},这样获得的总美味度为5+(-10)+15=10,花费的总钱数为(1*2^2+2*2)+(1*3^2+1*3)=20,两者相减为-10。
所以Kiana会选择方案9,这时她获得的总美味度减去花费的总钱数的值最大为12。
题解:考试的时候一眼就感觉是网络流,然后犹豫了下是最小割还是费用流,大致怎么连边也差不多了,然后就是没看出来是最大权闭合图(因为普通的最小割无法处理负权),最后写了个DFS交上去了~
感觉是时候重新写一篇植物大战僵尸的博客了,连最大权闭合图都忘了~
正题:我们先把d[i][j]列出来(由于样例给的是下三角所以不容易看出来)
5 -10 15
-10 15
15
所以当我们取d[i][j]的时候,相当于表格中在d[i][j]左下方的点全都要取,这好像需要连很多边,但其实我们只需要连左边和下面的两个点就可以了(即d[i+1][j]和d[i][j-1]),因为如果取这两个点,其左下角的点一定都取完了
然后根据最大权闭合图的连边方法:
从S向所有正权的点连边,边权为该点权值;
从所有负权的点向T连边,边权为该点权值相反数;
从所有的寿司编号向T连边,边权为m*编号的平方;
从所有的d[i][i]向T连边,边权为编号;
从所有的d[i][i]向该寿司的编号连边,边权为∞;
从所有的d[i][j](i<j)向d[i+1][j]和d[i][j-1]连边,边权为∞;
讲道理代码一点也不长
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
int n,m,cnt,tot,sum,S,T,ans;
int to[1000000],next[1000000],val[1000000],head[10000];
int map[110][110],num[110][110],A[1010],d[10000];
queue<int> q;
int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9'){if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
void add(int a,int b,int c)
{
to[cnt]=b,val[cnt]=c,next[cnt]=head[a],head[a]=cnt++;
to[cnt]=a,val[cnt]=0,next[cnt]=head[b],head[b]=cnt++;
}
int bfs()
{
while(!q.empty()) q.pop();
memset(d,0,sizeof(d));
d[S]=1,q.push(S);
int i,u;
while(!q.empty())
{
u=q.front(),q.pop();
for(i=head[u];i!=-1;i=next[i])
{
if(!d[to[i]]&&val[i])
{
d[to[i]]=d[u]+1;
if(to[i]==T) return 1;
q.push(to[i]);
}
}
}
return 0;
}
int dfs(int x,int mf)
{
if(x==T) return mf;
int i,k,temp=mf;
for(i=head[x];i!=-1;i=next[i])
{
if(d[to[i]]==d[x]+1&&val[i])
{
k=dfs(to[i],min(temp,val[i]));
if(!k) d[to[i]]=0;
val[i]-=k,val[i^1]+=k,temp-=k;
if(!temp) break;
}
}
return mf-temp;
}
int main()
{
n=rd(),m=rd();
int i,j,a;
T=n+n*(n+1)/2+1;
tot=n;
memset(head,-1,sizeof(head));
for(i=1;i<=n;i++)
{
a=rd();
if(!A[a]) A[a]=++tot,add(tot,T,m*a*a);
add(i,T,a),add(i,A[a],1<<30);
}
for(i=1;i<=n;i++)
for(j=i;j<=n;j++)
num[i][j]=(i==j)?i:(++tot);
for(i=1;i<=n;i++)
{
for(j=i;j<=n;j++)
{
map[i][j]=rd();
if(i!=j) add(num[i][j],num[i][j-1],1<<30),
add(num[i][j],num[i+1][j],1<<30);
if(map[i][j]<0) add(num[i][j],T,-map[i][j]);
else add(S,num[i][j],map[i][j]),sum+=map[i][j];
}
}
while(bfs()) ans+=dfs(S,1<<30);
printf("%d",sum-ans);
return 0;
}
【BZOJ4873】[Shoi2017]寿司餐厅 最大权闭合图的更多相关文章
- BZOJ4873[Shoi2017]寿司餐厅——最大权闭合子图
题目描述 Kiana最近喜欢到一家非常美味的寿司餐厅用餐.每天晚上,这家餐厅都会按顺序提供n种寿司,第i种寿司有一个 代号ai和美味度di,i,不同种类的寿司有可能使用相同的代号.每种寿司的份数都是无 ...
- 【最大权闭合子图】bzoj4873 [Shoi2017]寿司餐厅
4873: [Shoi2017]寿司餐厅 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 369 Solved: 256[Submit][Status ...
- bzoj4873: [Shoi2017]寿司餐厅(最大权闭合子图)
4873: [Shoi2017]寿司餐厅 大难题啊啊!!! 题目:传送门 题解:一眼题是网络流,但还是不会OTZ,菜啊... %题解... 最大权闭合子图!!! 好的...开始花式建边: 1.对于每个 ...
- [BZOJ4873][六省联考2017]寿司餐厅(最大权闭合子图)
4873: [Shoi2017]寿司餐厅 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 490 Solved: 350[Submit][Status ...
- BZOJ4873 [Shoi2017]寿司餐厅 【最大权闭合子图】
题目链接 BZOJ4873 题解 题意很鬼畜,就可以考虑网络流[雾] 然后就会发现这是一个裸的最大权闭合子图 就是注意要离散化一下代号 #include<algorithm> #inclu ...
- bzoj4873 [Shoi2017]寿司餐厅
Input 第一行包含两个正整数n,m,分别表示这家餐厅提供的寿司总数和计算寿司价格中使用的常数. 第二行包含n个正整数,其中第k个数ak表示第k份寿司的代号. 接下来n行,第i行包含n-i+1个整数 ...
- [HEOI2017] 寿司餐厅 + 最大权闭合子图的总结
Description 太长了自己看叭 点这里! Solution 先学一波什么叫最大权闭合子图. 先要明白什么是闭合子图,闭合子图就是给定一个有向图,从中选择一些点组成一个点集V.对于V中任意一个点 ...
- BZOJ4873 Shoi2017寿司餐厅(最小割)
选择了某个区间就必须选择其所有子区间,容易想到这是一个最大权闭合子图的模型.考虑将区间按长度分层,相邻层按包含关系连边,区间[i,j]的权值即di,j,其中最后一层表示长度为1的区间的同时也表示寿司本 ...
- bzoj4873: [Shoi2017]寿司餐厅(最小割)
传送门 大佬们是怎么一眼看出这是一个最大权闭合子图的……大佬好强->这里 1.把所有区间$(i,j)$看成一个点,如果权值大于0,则从$S$向他连边,容量为权值,否则从它向$T$连边,容量为权值 ...
随机推荐
- machine_learning-knn算法具体解释(近邻算法)
近邻算法是机器学习算法中的入门算法,该算法用于针对已有数据集对未知数据进行分类. 该算法核心思想是通过计算预測数据与已有数据的相似度猜測结果. 举例: 如果有例如以下一组数据(在下面我们统一把该数据作 ...
- Lintcode---克隆二叉树
深度复制一个二叉树. 给定一个二叉树,返回一个他的 克隆品 . 您在真实的面试中是否遇到过这个题? Yes 样例 给定一个二叉树: 1 / \ 2 3 / \ 4 5 返回其相同结构相同数值的克隆二叉 ...
- C++ 多线程(两个线程卖火车票)
#include <windows.h> #include <iostream.h> DWORD WINAPI Fun1Proc(LPVOID lpParameter);//t ...
- win10 配置 python3 + opencv3.2 + VideoCapture
最近需要在 win10 上进行图片处理,使用深度学习框架 tensorflow ,所以安装了python3.5 + opencv3.2 + tensorflow + VideoCapture + PI ...
- jquery获取元素索引值index()
jquery获取元素索引值index()方法实例. jquery获取元素索引值index()方法: jquery的index()方法 搜索匹配的元素,并返回相应元素的索引值,从0开始计数. 如果不给 ...
- 【Android】13.2 使用自定义的CursorAdapter访问SQLite数据库
分类:C#.Android.VS2015: 创建日期:2016-02-26 一.简介 SQliteDemo1的例子演示了SimpleCursorAdapter的用法,本节我们将使用用途更广的自定义的游 ...
- linux命令汇总1
允许非root用户使用“sudo” root身份登录系统,执行“visudo”,根据示例添加新的一个规则(记住输入的密码是当前用户密码,而不是root密码)#不需要密码执行sudo命令hadoop ...
- ntoj 808 蚂蚁的难题(八)
蚂蚁的难题(八) 时间限制:2000 ms | 内存限制:65535 KB 难度:5 描述 蚂蚁是一个古玩爱好者,他收藏了很多瓶瓶罐罐. 有一天,他要将他的宝贝们一字排开, 摆放到一个长度为L的展 ...
- 高效学习Oracle的方法论
Oracle的很多经验并不是来自工业环境.很多问题和经验都可以从自己的测试里积累 实验要做,但也要想! 那思维的起点是什么? 以下是我的看法.或者有些不合理: ...
- 基于jQuery左侧小图滚动右侧大图显示代码
今天给大家分享一款 jQuery左侧小图滚动右侧大图显示代码是一款基于jQuery实现的左侧滚动图片点击大图查看效果代码.该实例适用浏览器:IE8.360.FireFox.Chrome.Safari. ...