bzoj1930

1930: [Shoi2003]pacman 吃豆豆

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 1923  Solved: 435
[Submit][Status][Discuss]

Description

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

Input

第一行为一个整数N,表示豆豆的数目。 接下来 N 行,每行一对正整数,表示第i个豆豆的坐标。任意两个豆豆的坐标都不会重合。

Output

仅有一行包含一个整数,即两个PACMAN加起来最多能吃掉的豆豆数量

Sample Input

8

8 1

1 5

5 7

2 2

7 8

4 6

3 3

6 4

Sample Output

7

HINT

N < = 2000

Source

666 卡内存,zky大神只用了2000kb

很容易想出这是个最大费用流。但是很明显,2000*2000的边很容易tle,那么我们要进行剪枝。如果a->b,b->c,那么a->c是没有必要的。

但是还卡空间,因此我们可以用short。。。 连边:s:原点 ss:原点拆开的点,t:汇点

link(s,ss,f=2,c=0) for each i link(ss,i,f=2,c=0) link(i+n(拆点),t,f=2,c=0)

每个点和可以到达的点:link(i+n,j,f=1,c=1) link(i+n,j,f=1,c=1) 并且我们先按x排序,从x小到大枚举,如果当前的y比之前最小值要大,那么肯定之前连过,不用连了。

#include<bits/stdc++.h>
using namespace std;
#define inf (1<<30)
#define N 2010
struct edge
{
    short f,c,to;
    int nxt;
}e[4500010];
struct data
{
    int x,y;
}x[4010];
int cnt=1,s,t,ss,n;
int pree[4010],prev[4010],dist[4010],head[4010];
short q[4200010];
inline bool cp(data x,data y)
{
    if(x.x!=y.x) return x.x<y.x;
    return x.y<y.y;
}
inline int min(int x,int y)
{
    return x<y?x:y;
}
inline void link(int u,int v,int f,int c)
{
    e[++cnt].nxt=head[u];
    head[u]=cnt;
    e[cnt].to=v;
    e[cnt].f=f;
    e[cnt].c=c;
}
inline void ins(int u,int v,int c,int f)
{
    link(u,v,f,c);  link(v,u,0,-c);
}
inline bool spfa()
{
    memset(dist,-1,sizeof(dist));
    int l=1,r=0;
    q[++r]=s; dist[s]=0;
    while(l<=r)
    {
        int u=q[l++];
        for(int i=head[u];i;i=e[i].nxt) if(e[i].f&&dist[e[i].to]<dist[u]+e[i].c)
        {
            prev[e[i].to]=u;
            pree[e[i].to]=i;
            dist[e[i].to]=dist[u]+e[i].c;
            q[++r]=e[i].to;
        }
    }
    return dist[t]!=-1;
}
inline int flow()
{
    int u=t,delta=inf;
    while(u!=s)
    {
        delta=min(delta,e[pree[u]].f);
        u=prev[u];
    }
    u=t;
    while(u!=s)
    {
        e[pree[u]].f-=delta;
        e[pree[u]^1].f+=delta;
        u=prev[u];
    }
    return dist[t]*delta;
}
inline void MinCostFlow()
{
    int ans=0,cur=0;
    while(spfa())
    {
        cur+=flow();
        if(cur>ans) ans=cur;
    }
    printf("%d\n",ans);
}
int main()
{
    scanf("%d",&n); s=2*n+1; t=2*n+2; ss=s+2;
    for(int i=1;i<=n;i++) scanf("%d%d",&x[i].x,&x[i].y);
    ins(s,ss,0,2);
    for(int i=1;i<=n;i++)
    {
        ins(ss,i,0,2);
        ins(i+n,t,0,2);
    }
    sort(x+1,x+n+1,cp);
    for(int i=1;i<=n;i++)
    {
        ins(i,i+n,1,1);
        ins(i,i+n,0,1);
        int top=inf;
        for(int j=i+1;j<=n;j++)
            if(x[j].y<top&&x[i].y<=x[j].y)
                ins(i+n,j,0,2),top=x[j].y;
    }
    MinCostFlow();
    return 0;
} 

时间: 2024-11-05 03:51:48

bzoj1930的相关文章

BZOJ1930 [Shoi2003]pacman 吃豆豆

SHOI出过这么鬼的题?..跪 首先我们可以想到费用网络流,找一个流量为2的最大费用流即可,问题是怎么建图 因为针对点才有收益,而且收益只有一次,所以考虑拆点,不妨设一个点p拆成入点p1和出点p2 则p1 -> p2连边流量为1,费用为1:再连边流量为1,费用为0:S向p1连边流量为1,费用为0:p2向T连边,流量为1,费用为0 若p能到达q,则p2 -> q1连边,流量为2,费用为0 然后会发现边太多...优化? 如果i能到达j,j能到达k,则i不要向k连边,于是就是一个单调性的问题,对点按

【BZOJ1930】【SHOI2003】吃豆豆

初见杀-- 原题: 两个PACMAN吃豆豆.一开始的时候,PACMAN都在坐标原点的左下方,豆豆都在右上方.PACMAN走到豆豆处就会吃掉它.PACMAN行走的路线很奇怪,只能向右走或者向上走,他们行走的路线不可以相交. 请你帮这两个PACMAN计算一下,他们俩加起来最多能吃掉多少豆豆. N < = 2000 一眼秒掉,拆点费用流 然后发现内存64M???减少边的数组,提交,RE-- 看chty的题解,更换建图方式,减少边数,提交,WA-- 然后我的上午没了 解题思路很简单,拆点费用流即可,关键

BZOJ1930 [Shoi2003]pacman 吃豆豆 费用流

题目大意:在二维平面上有若干个点,求出两条不相交的二维LIS,使得上面包含的点的数目最多. 思路1:暴力建图 注意到不相交这个条件根本没用,画图可以发现如果相交的话,我们总可以通过交换一些点使得两个序列不相交. 那么问题转化为求出两个没有公共点的上升子序列,使得长度之和最大. 对于这种情况我们利用最大费用流求解. 设(a,b)分别表示一条有向边的流量和费用. S->S' (2,0) S'->x(1,0),x'->T(1,0)(1<=x<=n) x->x' (1,1) 表

大神刷题表

9月27日 后缀数组:[wikioi3160]最长公共子串 dp:NOIP2001统计单词个数 后缀自动机:[spoj1812]Longest Common Substring II [wikioi3160]最长公共子串 [spoj7258]Lexicographical Substring Search 扫描线+set:[poj2932]Coneology 扫描线+set+树上删边游戏:[FJOI2013]圆形游戏 结论:[bzoj3706][FJ2014集训]反色刷 最小环:[poj1734

[转载]hzwer的bzoj题单

counter: 664BZOJ1601 BZOJ1003 BZOJ1002 BZOJ1192 BZOJ1303 BZOJ1270 BZOJ3039 BZOJ1191 BZOJ1059 BZOJ1202 BZOJ1051 BZOJ1001 BZOJ1588 BZOJ1208 BZOJ1491 BZOJ1084 BZOJ1295 BZOJ3109 BZOJ1085 BZOJ1041 BZOJ1087 BZOJ3038 BZOJ1821 BZOJ1076 BZOJ2321 BZOJ1934 BZOJ