【BZOJ 4873】【2017六省联考】寿司餐厅
2017-04-27 14:28
381 查看
对于m=0,相当于每个寿司的价格是独立的,那么设f[i][j]表示i到j这个区间寿司全部被取的最大美味度,显然f[i][j]可以从它的子区间得到。然后dp组合一下若干个区间就好了,60分感人。
正解是最大权闭合子图,把每个区间f[i][j]看作是一个节点A(i,j),把每个寿司看作是一个节点B(i),有如下约束条件:
1、取了A(i,j),一定要取A(i+1,j)和A(i,j-1);
2、取了A(i,i),一定要取B(i);
然后所有d[i][j]为正的向S连边,负的向T连边,B向T连边,这样是60分的建图;对于满分算法,只需对每个代号为x的B向C(x)连边,然后C(x)再向T连边即可。
至于跑最大权闭合子图,只要将S连出的边权和减去最小割即是答案;至于最小割那就是Dinic跑一下最大流就好了。
网上的题解一般都是提前处理一次项的价格(直接扣在B的权上),直接做应该也行。
不知道为什么被卡!明明前19个点都是秒出最后一个点直接卡上天。。。BZOJ上面跑了8s+才过掉。。后来一想好像BZOJ算的是总时间。。。因为最后一个点才跑8s。。。
正解是最大权闭合子图,把每个区间f[i][j]看作是一个节点A(i,j),把每个寿司看作是一个节点B(i),有如下约束条件:
1、取了A(i,j),一定要取A(i+1,j)和A(i,j-1);
2、取了A(i,i),一定要取B(i);
然后所有d[i][j]为正的向S连边,负的向T连边,B向T连边,这样是60分的建图;对于满分算法,只需对每个代号为x的B向C(x)连边,然后C(x)再向T连边即可。
至于跑最大权闭合子图,只要将S连出的边权和减去最小割即是答案;至于最小割那就是Dinic跑一下最大流就好了。
网上的题解一般都是提前处理一次项的价格(直接扣在B的权上),直接做应该也行。
不知道为什么被卡!明明前19个点都是秒出最后一个点直接卡上天。。。BZOJ上面跑了8s+才过掉。。后来一想好像BZOJ算的是总时间。。。因为最后一个点才跑8s。。。
#include<cmath> #include<cstdio> #include<vector> #include<queue> #include<cstring> #include<iomanip> #include<stdlib.h> #include<iostream> #include<algorithm> #define ll long long #define inf 0x7fffffff #define mod 1000000007 #define N 200 #define NN N*N+N*10 #define fo(i,a,b) for(i=a;i<=b;i++) #define fd(i,a,b) for(i=a;i>=b;i--) using namespace std; queue<int> q; struct NetWorkFlow{int to,nxt,flow;} edge[NN*2]; int dep[NN],head[NN],a[NN],cnt,d ,num ; int AN,s,t,n,m,tot,i,j,sum; void add(int x,int y,int z) { edge[++tot].to = y; edge[tot].nxt = head[x]; edge[tot].flow = z; head[x] = tot; } int bfs() { int i; q.push(s); dep[s] = 1; while (!q.empty()) { int nw = q.front(); q.pop(); for (i = head[nw]; i ; i = edge[i].nxt) { int nt = edge[i].to; if (dep[nt] == 0 && edge[i].flow) {q.push(nt); dep[nt] = dep[nw] + 1;} } } return dep[t]; } int dfs(int nw,int MinFlow) { int ResFlow = 0; int i; if (nw == t || MinFlow <= 0) return MinFlow; for (i = head[nw]; i ; i = edge[i].nxt) { int nt = edge[i].to; if (dep[nt] == dep[nw] + 1) { int temp = dfs(nt,min(MinFlow,edge[i].flow)); edge[i^1].flow += temp; edge[i].flow -= temp; MinFlow -= temp; ResFlow += temp; if (!MinFlow) break; } } return ResFlow; } int MinCut() { int res = 0; memset(dep,0,sizeof(dep)); while (bfs()) { res += dfs(s,inf); memset(dep,0,sizeof(dep)); } return res; } int main() { scanf("%d%d",&n,&m); fo(i,1,n) scanf("%d",&a[i]); memset(head,0,sizeof(head)); AN = 1000; s = 1; t = s + AN + n * n + 1; tot = 1; fo(i,1,AN) { add(s+i,t,m*i*i); add(t,s+i,0); } cnt = 1; fo(i,1,n) fo(j,i,n) { scanf("%d",&d[i][j]); num[i][j] = s + AN + cnt; cnt++; } fo(i,1,n) fo(j,i,n) { if (i == j) { d[i][j] -= a[i]; add(num[i][j],s+a[i],inf); add(s+a[i],num[i][j],0); } else { add(num[i][j],num[i+1][j],inf); add(num[i+1][j],num[i][j],0); add(num[i][j],num[i][j-1],inf); add(num[i][j-1],num[i][j],0); } if (d[i][j] > 0) { sum += d[i][j]; add(s,num[i][j],d[i][j]); add(num[i][j],s,0); } else { 4000 add(num[i][j],t,-d[i][j]); add(t,num[i][j],0); } } printf("%d\n",sum-MinCut()); return 0; }
相关文章推荐
- 【BZOJ】4873: [Shoi2017]寿司餐厅
- BZOJ4873:[SHOI2017]寿司餐厅——题解
- bzoj 4873: [Shoi2017]寿司餐厅 [最小割]
- BZOJ 4873: [Shoi2017]寿司餐厅 (最大权闭合子图)
- 【BZOJ4873】[Shoi2017]寿司餐厅 最大权闭合图
- BZOJ4873 [Shoi2017]寿司餐厅
- BZOJ_4873_[Shoi2017]寿司餐厅_最大权闭合子图
- BZOJ4873: [Shoi2017]寿司餐厅
- 【BZOJ4873】【SHOI2017】寿司餐厅
- bzoj 4873: [Shoi2017]寿司餐厅 最大权闭合子图
- BZOJ 4873 [Shoi2017]寿司餐厅 | 网络流 最大权闭合子图
- BZOJ:4873: [Shoi2017]寿司餐厅
- BZOJ4873 寿司餐厅
- bzoj千题计划265:bzoj4873: [六省联考2017]寿司餐厅
- [最大权闭合子图] BZOJ 4873 [Shoi2017]寿司餐厅
- 4873: [Shoi2017]寿司餐厅
- 黑吉辽沪冀晋六省联考 2017 BZOJ 4868&4869&4870&4871&4872&4873
- 洛谷3749 [六省联考2017]寿司餐厅
- [最大权闭合子图][最小割] BZOJ 4873:寿司餐厅
- [BZOJ4873][六省联考2017]寿司餐厅(最大权闭合子图)