• bzoj 1930: [Shoi2003]pacman 吃豆豆 [费用流]


    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
    ", 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)
    ", 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
    ", ans);
    }
    
  • 相关阅读:
    使用Vue快速开发单页应用
    轻松入门React和Webpack
    使用Redux管理你的React应用
    深入理解 react-router 路由系统
    webpack学习之路
    webpack编译流程漫谈
    HTML5无刷新修改Url,history pushState/replaceState
    gulp的流与执行顺序
    RequireJS对文件合并与压缩实现方法
    RequireJS模块化后JS压缩合并
  • 原文地址:https://www.cnblogs.com/candy99/p/6854043.html
Copyright © 2020-2023  润新知