传送门

大佬们是怎么一眼看出这是一个最大权闭合子图的……大佬好强->这里

1.把所有区间$(i,j)$看成一个点,如果权值大于0,则从$S$向他连边,容量为权值,否则从它向$T$连边,容量为权值的相反数

2.对于区间$(i,j)$,向所有的寿司$i$到$j$连边,表示选这个区间这些寿司必须选

3.对每一个寿司类型$w[i]$,为他们各自开一个点,向$T$连边,容量为$m*w[i]*w[i]$

4.对每一个寿司向他们所属的类型$w[i]$连边,容量为$inf$,向$T$连边,容量为$w[i]$

5.对于所有区间$(i,j)$,向区间$(i-1,j),(i,j-1)$连边,容量$inf$,表示选了大的必须选小的

然后用总收益减去最小割就行了

 //minamoto
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define inf 0x3f3f3f3f
#define ll long long
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
const int N=,M=;
int head[N],Next[M],ver[M],edge[M],tot=;
int dep[N],cur[N],S,T;
queue<int> q;
inline void add(int u,int v,int e){
ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e;
ver[++tot]=u,Next[tot]=head[v],head[v]=tot,edge[tot]=;
}
bool bfs(){
while(!q.empty()) q.pop();
for(int i=S;i<=T;++i) cur[i]=head[i];
memset(dep,-,sizeof(dep));
q.push(S),dep[S]=;
while(!q.empty()){
int u=q.front();q.pop();
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(dep[v]<&&edge[i]){
dep[v]=dep[u]+,q.push(v);
if(v==T) return true;
}
}
}
return false;
}
int dfs(int u,int limit){
if(u==T||!limit) return limit;
int flow=,f;
for(int i=cur[u];i;i=cur[u]=Next[i]){
int v=ver[i];
if(dep[v]==dep[u]+&&(f=dfs(v,min(limit,edge[i])))){
flow+=f,limit-=f;
edge[i]-=f,edge[i^]+=f;
if(!limit) break;
}
}
if(!flow) dep[u]=-;
return flow;
}
int dinic(){
int flow=;
while(bfs()) flow+=dfs(S,inf);
return flow;
}
int n,m,a[],mp[][],id[][],cnt=;
int idw[];bool vis[];ll sum=;
void build(){
S=;
for(int i=;i<=n;++i)
for(int j=;j<=n;++j)
id[i][j]=++cnt;
for(int i=;i<=n;++i)
if(!vis[a[i]]) vis[a[i]]=,idw[a[i]]=++cnt;
T=cnt+n+;
memset(vis,,sizeof(vis));
for(int i=;i<=n;++i)
if(!vis[a[i]]) vis[a[i]]=,add(idw[a[i]],T,m*a[i]*a[i]);
for(int i=;i<=n;++i)
add(i+cnt,idw[a[i]],inf),add(i+cnt,T,a[i]);
for(int i=;i<=n;++i)
for(int j=i;j<=n;++j){
if(mp[i][j]>){
sum+=mp[i][j];
add(S,id[i][j],mp[i][j]);
add(id[i][j],i+cnt,inf);
add(id[i][j],j+cnt,inf);
}
else if(mp[i][j]<){
add(id[i][j],T,-mp[i][j]);
add(id[i][j],i+cnt,inf);
add(id[i][j],j+cnt,inf);
}
if(i!=j){
add(id[i][j],id[i+][j],inf);
add(id[i][j],id[i][j-],inf);
}
}
}
int main(){
//freopen("testdata.in","r",stdin);
n=read(),m=read();
for(int i=;i<=n;++i) a[i]=read();
for(int i=;i<=n;++i)
for(int j=i;j<=n;++j)
mp[i][j]=read();
build();
printf("%lld\n",sum-dinic());
return ;
}

bzoj4873: [Shoi2017]寿司餐厅(最小割)的更多相关文章

  1. bzoj 4873: [Shoi2017]寿司餐厅 [最小割]

    4873: [Shoi2017]寿司餐厅 题意:略 唯一会做的... 一眼最小割 就是最大权闭合子图呀 \(s\rightarrow d_{positive} \rightarrow -d_{negt ...

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

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

  3. bzoj4873: [Shoi2017]寿司餐厅(最大权闭合子图)

    4873: [Shoi2017]寿司餐厅 大难题啊啊!!! 题目:传送门 题解:一眼题是网络流,但还是不会OTZ,菜啊... %题解... 最大权闭合子图!!! 好的...开始花式建边: 1.对于每个 ...

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

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

  5. bzoj4873 [Shoi2017]寿司餐厅

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

  6. P3749 [六省联考2017]寿司餐厅 最小割

    \(\color{#0066ff}{ 题目描述 }\) Kiana 最近喜欢到一家非常美味的寿司餐厅用餐. 每天晚上,这家餐厅都会按顺序提供 \(n\) 种寿司,第 \(i\) 种寿司有一个代号 \( ...

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

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

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

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

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

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

随机推荐

  1. Python—numpy.argsort()

    函数将数组的值从小到大排序后,并按照其相对应的索引值输出. 一维数组: >>> a = array([3,1,2]) >>> argsort(a) array([1 ...

  2. Selenium-元素定位与操作

    UI的自动化本质就是识别元素,操作元素,而元素的识别就是通过HTML的标签和属性,所以对于基本的HTML的只是是必备的 随着页面复杂度的提升,加之很多公司的开发也没有统一规范,这就给识别元素造成了非常 ...

  3. AngularJS-指令command

    directive: 匹配模式restrict:'AEMC'默认为A template templateUrl templateCache:把模板缓存起来,共多个指令使用 var myModule = ...

  4. stl_iterator.h

    stl_iterator.h // Filename: stl_iterator.h // Comment By: 凝霜 // E-mail: mdl2009@vip.qq.com // Blog: ...

  5. bzoj3573米特运输

    题意: 给定一棵树上的边和点权 改动点权使得每个父节点u容量为子节点容量的d[u](子节点个数)倍 考察点: 1.这是一道语文题 2.点权很大 直接算会爆 有一种优化办法:取log(醉 这是什么优化) ...

  6. 洛谷P2896 [USACO08FEB]一起吃饭Eating Together

    题目描述 The cows are so very silly about their dinner partners. They have organized themselves into thr ...

  7. redis安装及启动及设置

    1. 安装 1.1 下载解压包,直接解压到任意路径下即可 windows下载地址:ttps://github.com/MSOpenTech/redis/releases 2.启动 2.1 启动要先开启 ...

  8. C# 自定义颜色

    一.需要引用 using System.Windows.Media; 二. 自定义颜色 通过自定义 RGB 的值来达到自定义颜色的目的 Color _Mycolor = Color.FromRgb(5 ...

  9. mysql错误代号大全

    B.1. 服务器错误代码和消息 服务器错误信息来自下述源文件: · 错误消息信息列在share/errmsg.txt文件中."%d"和"%s"分别代表编号和字符 ...

  10. C++之queue模板类

    1.queue常用成员函数 ①size() 返回队列中元素的个数 ②empty() 如果队列空则返回真  ③back() 返回最后一个元素引用即队尾. ④front() 返回第一个元素引用即队首. ⑤ ...