[HEOI2017] 寿司餐厅 + 最大权闭合子图的总结
Description
太长了自己看叭 点这里!
Solution
先学一波什么叫最大权闭合子图。
先要明白什么是闭合子图,闭合子图就是给定一个有向图,从中选择一些点组成一个点集V。对于V中任意一个点,其后续节点都仍然在V中。如果给点再加上点权那就会有很多问题可以转化成求最大权闭合子图了。
那怎么求这个最大权闭合子图呢?
可以用网络流的思想来求出来这个东西。
先说建图,如果一个点的权值是正的,那就让源点和这个点相连,流量是这个点的权值。如果一个点的权值是负的,那就让这个点和汇点相连,流量是这个点权值的绝对值。那些在原图中的边我们还是让两个端点相连,流量为正无穷。然后这张图的最小割就是我们要求的最大权闭合子图了。
证明:
先来证明两个引理:
1.最小割一定是简单割
所谓简单割就是割(S,T)中每条边都与S或T直接相连。
因为不与s,t相连的边就是原图中的那些边,它们的流量都为正无穷,所以包含流量为正无穷的边的割一定不是最小割。
2.一个简单割一定和一个闭合子图对应
我们将原图中的闭合子图V加上源点s构成S集,其余点和汇点构成T集。
首先证明闭合子图是简单割:若闭合子图对应的割不是简单割,那么就存在一条原图中的边(u,v),u∈S,v∈T,且flow(u,v)=inf。说明u的后续节点v不在S中,这与闭合子图的定义矛盾。
接着证明简单割是闭合子图,对于V中任意一个点u,u∈S。u的任意一条出边flow(u,v)=inf,一定不会在简单割的边集中,因此v不属于T,v∈S。符合闭合子图的定义。
由上面两个引理可以知道,最小割也对应了一个闭合子图,接下来证明最小割就是最大权的闭合子图。
首先有割的容量C(S,T)=T中所有正权点的权值之和+S中所有负权点的权值绝对值之和。
闭合子图的权值W=S中所有正权点的权值之和-S中所有负权点的权值绝对值之和。
则有C(S,T)+W=T中所有正权点的权值之和+S中所有正权点的权值之和=所有正权点的权值之和。
所以W=所有正权点的权值之和-C(S,T)
由于所有正权点的权值之和是一个定值,那么割的容量越小,W也就越大。因此当C(S,T)取最小割时,W也就达到了最大权。
证毕。
那有一些最大权闭合子图的裸题就可以做了,比如说 拍照 太空飞行计划问题
然后我们再回过头来看这道题。
哦对了,最大权闭合子图的模型大概长这样:
- 选一些点必须要选其他点
- 每个点最多选一次
- 有点权
- 求最大点权和
熟练的话大概可以猜到这是一道最大权闭合子图的题?
于是直接建模九星了
- 超级源点S向正美味度的区间连一条流量为美味度的边
- 负美味度区间向超级汇点连一条流量为美味度绝对值的边
- 区间[i,j]向区间[i+1,j],[i,j-1]分别连一条流量为inf的边
- 区间[i,i]向寿司i连一条流量为inf的边
- 寿司i向超级汇点连一条流量为寿司代号的边
- 寿司i向其代号连一条流量为inf的边
- 寿司代号i向超级汇点连一条流量为m*i*i的边
然后是吐槽...
做这题时非要递归连边然后没注意一个区间可能被递归到了好几次(或许是好几万次)就直接导致一个n=30的数据点我连了三十亿条边mdzz
哦对了顺便%yzy学长他考场上秒切了这题orzzzzz
Code
#include<bits/stdc++.h>
using std::min;
using std::max;
using std::swap;
using std::vector;
typedef double db;
typedef long long ll;
#define pb(A) push_back(A)
#define pii std::pair<int,int>
#define all(A) A.begin(),A.end()
#define mp(A,B) std::make_pair(A,B)
const int N=105;
const int M=1e5+5;
const int inf=1e9;
int head[M],d[M];
int n,m,s,t;ll cnt=1,a[N];
int dis[N][N],tot,vis[N*10];
struct Edge{
int to,nxt,flow;
}edge[1000005];
void add(int x,int y,int z){
edge[++cnt].to=y;
edge[cnt].nxt=head[x];
edge[cnt].flow=z;
head[x]=cnt;
}
int getint(){
int X=0,w=0;char ch=getchar();
while(!isdigit(ch))w|=ch=='-',ch=getchar();
while( isdigit(ch))X=X*10+ch-48,ch=getchar();
if(w) return -X;return X;
}
bool bfs(){
std::queue<int> q;q.push(s);
memset(d,0,sizeof d);d[s]=1;
while(q.size()){
int u=q.front();q.pop();
for(int i=head[u];i;i=edge[i].nxt){
int to=edge[i].to;
if(!d[to] and edge[i].flow){
d[to]=d[u]+1;
q.push(to);
if(to==t) return 1;
}
}
} return 0;
}
int dinic(int now,int flow){
if(now==t) return flow;
int res=flow;
for(int i=head[now];i;i=edge[i].nxt){
int to=edge[i].to;
if(d[to]==d[now]+1 and edge[i].flow){
int k=dinic(to,min(edge[i].flow,res));
if(!k) d[to]=0;
edge[i].flow-=k;edge[i^1].flow+=k;res-=k;
if(!res) return flow;
}
} return flow-res;
}
int calc(int x,int y){
int now=(x-1)*(n+n-(x-1)+1)/2;
return now+y-x+1;
}
signed main(){
n=getint(),m=getint();ll ans=0;
tot=n*(n+1)/2;t=tot+n+1001;
for(int i=1;i<=n;i++) a[i]=getint();
for(int i=1;i<=n;i++)
for(int j=i;j<=n;j++){
dis[i][j]=getint();
if(dis[i][j]>0) add(s,calc(i,j),dis[i][j]),add(calc(i,j),s,0),ans+=dis[i][j];
if(dis[i][j]<0) add(calc(i,j),t,-dis[i][j]),add(t,calc(i,j),0);
}
for(int i=1;i<=n;i++){
int x=calc(i,i);
add(x,tot+i,inf),add(tot+i,x,0);
for(int j=i+1;j<=n;j++){
int a=calc(i,j),b=calc(i,j-1),c=calc(i+1,j);
add(a,b,inf),add(b,a,0);
add(a,c,inf),add(c,a,0);
}
}
for(int i=1;i<=n;i++){
add(tot+i,tot+n+a[i],inf),add(tot+n+a[i],tot+i,0);
add(tot+i,t,a[i]),add(t,tot+i,0);
if(!vis[a[i]]){
add(tot+n+a[i],t,m*a[i]*a[i]),add(t,tot+n+a[i],0);
vis[a[i]]=1;
}
} ll flow=0,mxflow=0;
while(bfs()) while(flow=dinic(s,inf)) mxflow+=flow;
printf("%lld\n",ans-mxflow);
return 0;
}
[HEOI2017] 寿司餐厅 + 最大权闭合子图的总结的更多相关文章
- BZOJ4873[Shoi2017]寿司餐厅——最大权闭合子图
题目描述 Kiana最近喜欢到一家非常美味的寿司餐厅用餐.每天晚上,这家餐厅都会按顺序提供n种寿司,第i种寿司有一个 代号ai和美味度di,i,不同种类的寿司有可能使用相同的代号.每种寿司的份数都是无 ...
- [BZOJ4873][六省联考2017]寿司餐厅(最大权闭合子图)
4873: [Shoi2017]寿司餐厅 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 490 Solved: 350[Submit][Status ...
- 【BZOJ4873】[Shoi2017]寿司餐厅 最大权闭合图
[BZOJ4873][Shoi2017]寿司餐厅 Description Kiana最近喜欢到一家非常美味的寿司餐厅用餐.每天晚上,这家餐厅都会按顺序提供n种寿司,第i种寿司有一个代号ai和美味度di ...
- 【最大权闭合子图】bzoj4873 [Shoi2017]寿司餐厅
4873: [Shoi2017]寿司餐厅 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 369 Solved: 256[Submit][Status ...
- BZOJ_4873_[Shoi2017]寿司餐厅_最大权闭合子图
BZOJ_4873_[Shoi2017]寿司餐厅_最大权闭合子图 题意:http://www.lydsy.com/JudgeOnline/problem.php?id=4873 分析:我们发现分数正负 ...
- bzoj4873: [Shoi2017]寿司餐厅(最大权闭合子图)
4873: [Shoi2017]寿司餐厅 大难题啊啊!!! 题目:传送门 题解:一眼题是网络流,但还是不会OTZ,菜啊... %题解... 最大权闭合子图!!! 好的...开始花式建边: 1.对于每个 ...
- BZOJ 4873 [Shoi2017]寿司餐厅 | 网络流 最大权闭合子图
链接 BZOJ 4873 题解 当年的省选题--还记得蒟蒻的我Day1 20分滚粗-- 这道题是个最大权闭合子图的套路题.严重怀疑出题人就是先画好了图然后照着图编了个3000字的题面.和我喜欢的妹子当 ...
- BZOJ4873 [Shoi2017]寿司餐厅 【最大权闭合子图】
题目链接 BZOJ4873 题解 题意很鬼畜,就可以考虑网络流[雾] 然后就会发现这是一个裸的最大权闭合子图 就是注意要离散化一下代号 #include<algorithm> #inclu ...
- bzoj 4873: [Shoi2017]寿司餐厅【最大权闭合子图】
有正负收益,考虑最小割 因为有依赖关系,所以考虑最大权闭合子图 首先对每个d[i][j]建个点,正权连(s,id[i][j],d[i][j])并加到ans上,负权连(id[i][j],t,-d[i][ ...
随机推荐
- AX_Dialog
Dialog dialog = new Dialog("@SYS1052"); DialogField ...
- android studio 将自己的项目生成jar包
很多情况下我们开发的项目不是一个完整的app,而是完成一部分功能,供别人的app使用的情况.这时就需要将我们的项目打包生成jar或者arr库文件,让别人的app导入我们的jar包,就能直接使用我们项目 ...
- 无线网卡连接网络后共享给本地有线网卡使用(Win10)
无线网卡连接网络后共享给本地有线网卡使用(Win10) 1. 本文主要目的是介绍地有线网卡共享无线网卡的Wifi信号,该应用场景如下: 当在只有wifi环境下,同时有两台电脑A和B, A为笔记本: ...
- python模块:xml.dom.minidom
"""Simple implementation of the Level 1 DOM. Namespaces and other minor Level 2 featu ...
- mysql数据库的常用知识
问题一:如果使用可视化工具链接mysql? mysql默认情况下是不支持远程连接的!只需要几个步骤就能轻松搞定了. 1.vi /etc/mysql/my.cnf 修改里面bind-address项,将 ...
- jQuery应用实例2:表格隔行换色
这里是用JS实现的:http://www.cnblogs.com/xuyiqing/p/8376312.html 接下来利用上一篇提到的选择器利用jQuery实现: 发现原来多行代码这里只需要两行: ...
- Java学习笔记51(综合项目:家庭记账系统)
javaEE的开发模式 1.什么是模式 模式在开发过程中总结出的“套路”,总结出的一套约定俗成的设计模式 2.javaEE经历的模式 model1模式: 技术组成:jsp+javaBean model ...
- .NET手记-友盟消息推送服务器端加密算法的实现
最近为App开发消息推送功能,这里我们采用了友盟的消息推送服务,但其后台简陋,可定制化程度低,所以决定接入服务器端API,在自己的服务器上部署一套推送服务. 其中涉及到很多问题,首先要解决的就是与友盟 ...
- c++编程之内存的分配
当我们在进行编程时,特别是使用c++语言进行编程时,需要知道内存有几个内存区可供我们使用,因为c++可以直接操作内存.接下让我们来看看内存中的几大内存区. 1.栈区 栈区(stack)是速度最快的一个 ...
- 带你入门 Docker
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机制,相互之间不会有任何 ...