1930: [Shoi2003]pacman 吃豆豆

题意:两个PACMAN吃豆豆。一开始的时候,PACMAN都在坐标原点的左下方,豆豆都在右上方。PACMAN走到豆豆处就会吃掉它。PACMAN行走的路线很奇怪,只能向右走或者向上走,他们行走的路线不可以相交。 请你帮这两个PACMAN计算一下,他们俩加起来最多能吃掉多少豆豆。


暴力建图会被卡内存,可以按lis剖分建图...

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
#define fir first
#define sec second
const int N = 5005, M = 1e6+5, mo = 1e9+7;
inline int read() {
char c=getchar(); int x=0,f=1;
while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
return x*f;
} int n, s, t, ss, tt;
struct meow {
int x, y;
bool operator <(const meow &r) const {return x == r.x ? y < r.y : x < r.x;}
} a[2005]; struct edge {int v, ne, c, f, w;} e[M];
int cnt = 1, h[N];
inline void ins(int u, int v, int c, int w) { //printf("ins %d --> %d\n", u, v);
e[++cnt] = (edge) {v, h[u], c, 0, w}; h[u] = cnt;
e[++cnt] = (edge) {u, h[v], 0, 0, -w}; h[v] = cnt;
} void build() {
s=0; ss=n+n+1; tt=n+n+2; t=n+n+3;
ins(s, ss, 2, 0); ins(tt, t, 2, 0);
static bool mark[N];
for(int i=1; i<=n; i++) {
ins(i, n+i, 1, 1); ins(i, n+i, 1, 0);
int high = 0;
for(int j=i-1; j>=1; j--)
if(a[j].y > high && a[j].y <= a[i].y) ins(j+n, i, 2, 0), high = a[j].y, mark[j] = 1;
if(!high) ins(ss, i, 2, 0);
}
for(int i=1; i<=n; i++) if(!mark[i]) ins(i+n, tt, 2, 0);
}
namespace flow {
int d[N], inq[N], q[N], head, tail;
pair<int, int> pre[N];
inline void lop(int &x) {if(x == N) x = 1; else if(x == 0) x = N-1;}
bool spfa() {
head = tail = 1;
//memset(d, -1, sizeof(d));
for(int i=s; i<=t; i++) d[i] = -1e9;
memset(inq, 0, sizeof(inq));
d[s] = 0; q[tail++] = s; inq[s] = 1;
pre[t].fir = -1;
while(head != tail) {
int u = q[head++]; inq[u] = 0; lop(head);
for(int i=h[u]; i; i=e[i].ne) if(e[i].c > e[i].f) {
int v = e[i].v;
if(d[v] < d[u] + e[i].w) {
d[v] = d[u] + e[i].w;
pre[v] = make_pair(u, i);
if(!inq[v]) {
inq[v] = 1;
//if(d[v] > d[q[head]]) head--, lop(head), q[head] = v;
//else q[tail++] = v, lop(tail);
q[tail++] = v; lop(tail);
}
}
}
}
return pre[t].fir != -1;
}
int mcmf() {
int flow = 0, cost = 0;
while(spfa()) {
int f = 1e9, x;
for(int i=t; i != s; i = pre[i].fir) x = pre[i].sec, f = min(f, e[x].c - e[x].f);
flow += f; cost += d[t] * f;
for(int i=t; i != s; i = pre[i].fir) x = pre[i].sec, e[x].f += f, e[x^1].f -= f;
}
return cost;
}
}
void print(meow &a) {printf("(%d, %d)\n", a.x, a.y);}
int main() {
freopen("in", "r", stdin);
n = read();
for(int i=1; i<=n; i++) a[i].x = read(), a[i].y = read();
sort(a+1, a+n+1);
//for(int i=1; i<=n; i++) print(a[i]);
build();
int ans = flow::mcmf();
printf("%d\n", ans);
}

bzoj 1930: [Shoi2003]pacman 吃豆豆 [费用流]的更多相关文章

  1. 1930: [Shoi2003]pacman 吃豆豆

    1930: [Shoi2003]pacman 吃豆豆 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1969  Solved: 461[Submit][ ...

  2. 【BZOJ1930】[Shoi2003]pacman 吃豆豆 最大费用最大流

    [BZOJ1930][Shoi2003]pacman 吃豆豆 Description 两个PACMAN吃豆豆.一开始的时候,PACMAN都在坐标原点的左下方,豆豆都在右上方.PACMAN走到豆豆处就会 ...

  3. 【BZOJ 1930】 [Shoi2003]pacman 吃豆豆 最大费用最大流

    如果你知道他是网络流的话你就很快会想到一个最大费用最大流的模型,然后你发现可能T,然而你发现你只用增广两次,然后你就开心的打了出来,然后发现被稠密图里spfa的丧病时间复杂度坑了,还是会T.于是我就开 ...

  4. BZOJ 1930 吃豆豆(费用流)

    首先这题的两条线不相交的限制可以去掉,因为如果相交的话把点换一换是不影响最终结果的. 剩下的费用流建图是显然的,把点拆为两个,建立超级源点s和源点ss汇点t,连边(s,ss,2,0). 对于每个点,连 ...

  5. BZOJ1930 [Shoi2003]pacman 吃豆豆

     dp,首先建出图,f[i][j]表示a吃到了i点,b吃到了j点的最大值,转移的时候转移拓扑序小的那一维,如果i拓扑序小于j,那么转移到f[k][j],否则转移到f[i][k],建出的图边数也要优化, ...

  6. [bzoj]1930 pacman吃豆豆

    Description 两个PACMAN吃豆豆.一开始的时候,PACMAN都在坐标原点的左下方,豆豆都在右上方.PACMAN走到豆豆处就会吃掉它.PACMAN行走的路线很奇怪,只能向右走或者向上走,他 ...

  7. 【BZOJ1930】【SHOI2003】吃豆豆

    初见杀…… 原题: 两个PACMAN吃豆豆.一开始的时候,PACMAN都在坐标原点的左下方,豆豆都在右上方.PACMAN走到豆豆处就会吃掉它.PACMAN行走的路线很奇怪,只能向右走或者向上走,他们行 ...

  8. BZOJ 3876 支线剧情 | 有下界费用流

    BZOJ 3876 支线剧情 | 有下界费用流 题意 这题题面搞得我看了半天没看懂--是这样的,原题中的"剧情"指的是边,"剧情点"指的才是点. 题面翻译过来大 ...

  9. 从多种角度看[BZOJ 1061] [NOI 2008]志愿者招募(费用流)

    从多种角度看[BZOJ 1061] [NOI 2008]志愿者招募(费用流) 题面 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难题:为即将启动的奥运 ...

随机推荐

  1. Spring学习日志之Spring MVC启动配置

    对DispatcherServlet进行配置 Spring MVC的配置实际上就是对DispatcherServlet的配置 public class DispatcherServletConfig ...

  2. vi 方向键和Backspace键失效问题的解决方法

    安装的ubuntu默认的编辑器是vi,遇到了两个问题: ① insert模式下,按方向键将产生A.B.C.D等字符,解决方案: :set nocompatible ② insert模式下Backspa ...

  3. UEP-保存

    uep的保存操作分为ajaxgrid和ajaxform两种方式 1.ajaxgrid public void storeInfoSave(){ try { //两个dataWrap 一个dataWra ...

  4. JavaScript八张思维导图—编程实践

    JS基本概念 JS操作符 JS基本语句 JS数组用法 Date用法 JS字符串用法 JS编程风格 JS编程实践 不知不觉做前端已经五年多了,无论是从最初的jQuery还是现在火热的Angular,Vu ...

  5. HashSet,LinkedHashSet,TreeSet的区别

    Set接口Set不允许包含相同的元素,如果试图把两个相同元素加入同一个集合中,add方法返回false.Set判断两个对象相同不是使用==运算符,而是根据equals方法.也就是说,只要两个对象用eq ...

  6. Linq 实例

    1.分页 ).Take(); 2.分组 1)一般分组 //根据顾客的国家分组,查询顾客数大于5的国家名和顾客数var 一般分组 = from c in ctx.Customers group c by ...

  7. 用IDEA/WebStrom 提交本地项目到Git/码云等

    以码云为例: 在码云上创建新的项目. webstrom/idea 打开本地项目

  8. Freemarker 入门示例

    初步学习freemarker ,先做一个简单的HelloWord程序! 新建一个WEB工程,下载(我使用的是freemarker-2.3.20)freemarker并导入freemarker.jar, ...

  9. linux 巨页使用测试

    这里记录测试巨页的mmap使用,测试代码和<linux 巨页使用测试以及勘误1>类似. 跟踪脚本如下: probe kernel.function("hugetlb_reserv ...

  10. 2017-07-12(touch df du)

    touch 作用:修改文件时间或者创建新文件 文件三个主要的变动时间 mtime 当文件的内容发生改变的时候,就会更新这个时间 ctime 当文件的权限与属性发生改变的时候,就会更新这个时间 atim ...