【BZOJ1930】[Shoi2003]pacman 吃豆豆

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

题解:由于只需要跑两次,所以可以采用费用流。首先我们不用考虑两条路径相交的情况,因为我们可以将相交的部分交换一下,就不相交了。

但是本题卡空间!!!所以有一个优化:如果a能到b,b能到c,则不需要连a到c的边。所以具体建边方法:

1. S -> i 容量1,费用0
2. i -> i' 容量1,费用1
3. i' -> j 容量2,费用0 (注意容量是2!因为我们的优化中相当于是用a-b-c替换了a-c)
4. i -> T 容量1,费用1

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
int n,cnt,sum,S,T,ans;
int inq[4020],dis[4020],head[4020],to[4000010],next[4000010],cost[4000010],flow[4000010],pv[4020],pe[4020];
struct node
{
int x,y;
}p[2010];
queue<int> q;
int bfs()
{
memset(dis,0xc0,sizeof(dis));
dis[S]=0,q.push(S);
int i,u;
while(!q.empty())
{
u=q.front(),q.pop(),inq[u]=0;
for(i=head[u];i!=-1;i=next[i]) if(dis[to[i]]<dis[u]+cost[i]&&flow[i])
{
pv[to[i]]=u,pe[to[i]]=i,dis[to[i]]=dis[u]+cost[i];
if(!inq[to[i]]) inq[to[i]]=1,q.push(to[i]);
}
}
return dis[T]>0;
}
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
inline void add(int a,int b,int c,int d)
{
to[cnt]=b,cost[cnt]=c,flow[cnt]=d,next[cnt]=head[a],head[a]=cnt++;
to[cnt]=a,cost[cnt]=-c,flow[cnt]=0,next[cnt]=head[b],head[b]=cnt++;
}
bool cmp(const node &a,const node &b)
{
return (a.x==b.x)?(a.y<b.y):(a.x<b.x);
}
int main()
{
n=rd(),S=0,T=2*n+1;
int i,j;
memset(head,-1,sizeof(head));
for(i=1;i<=n;i++) add(S,i,0,1),add(i+n,T,0,1),add(i,i+n,1,1),add(i,i+n,0,1),p[i].x=rd(),p[i].y=rd();
sort(p+1,p+n+1,cmp);
for(i=1;i<=n;i++)
{
int mn=1<<30;
for(j=i+1;j<=n;j++) if(p[j].y>=p[i].y&&p[j].y<mn) add(i+n,j,0,2),mn=p[j].y;
}
while(bfs())
{
int mf=1<<30;
for(i=T;i!=S;i=pv[i]) mf=min(mf,flow[pe[i]]);
sum+=mf,ans+=dis[T]*mf;
if(sum==2) break;
for(i=T;i!=S;i=pv[i]) flow[pe[i]]-=mf,flow[pe[i]^1]+=mf;
}
printf("%d",ans);
return 0;
}//13 1 1 2 2 3 3 4 4 5 5 6 6 1 3 2 4 3 5 4 6 5 7 6 8 4 1

【BZOJ1930】[Shoi2003]pacman 吃豆豆 最大费用最大流的更多相关文章

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

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

  2. BZOJ1930 [Shoi2003]pacman 吃豆豆

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

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

    1930: [Shoi2003]pacman 吃豆豆 题意:两个PACMAN吃豆豆.一开始的时候,PACMAN都在坐标原点的左下方,豆豆都在右上方.PACMAN走到豆豆处就会吃掉它.PACMAN行走的 ...

  4. 1930: [Shoi2003]pacman 吃豆豆

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

  5. 【BZOJ1930】【SHOI2003】吃豆豆

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

  6. [bzoj]1930 pacman吃豆豆

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

  7. 洛谷 P4066 [SHOI2003]吃豆豆 解题报告

    P4066 [SHOI2003]吃豆豆 题目描述 两个PACMAN吃豆豆.一开始的时候,PACMAN都在坐标原点的左下方,豆豆都在右上方.PACMAN走到豆豆处就会吃掉它.PACMAN行走的路线很奇怪 ...

  8. HTML5吃豆豆游戏开发实战(一)使用Canvas绘制游戏主角

    近期在学习HTML5.爱因斯坦曾说过,"最好的学习就是自己去经历". 于是.我想在学习HTML5的同一时候.做一款简单的小游戏,这样学习起来也会非常有趣的.我想做的是曾经小时候玩儿 ...

  9. css动画实现吃豆豆

    话不多说,直接上代码:(作为一个初学者写的代码,多么0基础都能看的懂吧.) HTML部分 <!DOCTYPE html> <html lang=en> <head> ...

随机推荐

  1. LoadRunner如何在脚本运行时修改log设置选项

    LoadRunner如何在脚本运行时修改log设置选项?答案是使用lr_set_debug_message函数: lr_set_debug_message Sets the message level ...

  2. socket websocket

    1.websocket客户端 websocket允许通过JavaScript建立与远程服务器的连接,从而实现客户端与服务器间双向的通信.在websocket中有两个方法: 1.send() 向远程服务 ...

  3. Vue webpack配置文件

    一.代码地址 github:https://github.com/MengFangui/VueWebpackConfig 二.配置说明 1.命令 (1)npm i 安装依赖包 (2)num run d ...

  4. Linux 平台如何查看某个进程的线程数?

    Linux 平台如何查看某个进程的线程数?   三种方法:1. 使用top命令,具体用法是 top -H 加上这个选项,top的每一行就不是显示一个进程,而是一个线程. 2. 使用ps命令,具体用法是 ...

  5. python 利用numpy进行数据分析

    一.numpy.loadtxt读取数据 data=numpy.loadtxt('数据路径.txt',delimiter=',',usecols=(0,1,2,3) , dtype=float)#读取后 ...

  6. 关于升级 phpStudy 中 MySQL 版本至 5.7.17

    mysql版本低于5.6 自动更新时间会报错.因此要升级mysql版本.综合网上资料和实际过程中遇到的问题,具体细节和注意事项如下: 1.从官网上下载高版本的 MySQL :https://dev.m ...

  7. @using (Html.BeginForm()) @using (Ajax.BeginForm(new AjaxOptions() { })) 区别

    @using (Html.BeginForm()) 返回页面 也是页面 都是返回页面 只是 多了一个 data-ajax="true"

  8. 算法基础:整数拆分问题(Golang实现)

    一个整数总能够拆分为2的幂的和.比如: 7=1+2+4 7=1+2+2+2 7=1+1+1+4 7=1+1+1+2+2 7=1+1+1+1+1+2 7=1+1+1+1+1+1+1 总共同拥有6种不同的 ...

  9. SpringCloud系列十二:手动创建Feign

    1. 回顾 上文讲解了自定义Feign.但是在某些场景下,前文自定义Feign的方式满足不了需求,此时可使用Feign Builder API手动创建Feign. 本文围绕以下场景,为大家讲解如何手动 ...

  10. Creating Dialogbased Windows Application (3) / 创建基于对话框的Windows应用程序(三)Checkbox的应用、窗体置顶、设置图标 / VC++, Windows

    创建基于对话框的Windows应用程序(三) —— Checkbox的应用.窗体置顶.设置图标 上一节创建的窗体应用程序中,我们用到了Button和StaticText这两个控件.这一节中我们将学习使 ...