P4066 [SHOI2003]吃豆豆

题目描述

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

输入输出格式

输入格式:

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

输出格式:

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

输入输出样例

输入样例#1:

8

8 1

1 5

5 7

2 2

7 8

4 6

3 3

6 4

输出样例#1:

7

说明:

N < = 2000


先考虑暴力一点的

其实应该算是个比较裸的费用流建模了。

拆点分别连容量和权值边各为1,代表通过这个点获得1且仅可以走一次。

源点1连源点2容量2,表示两个人走。其余容量inf,权值为0

关于两个人相交的部分,其实是无所谓的,可以交换

直接跑最大费用最大流即可


考虑优化

连边时连接了很多无用的边,比如某两个点本来就间接可达,又连接了直接的边。

我们可以只连间接可达的边。然而这样会出现问题,因为我们限制了一个点只能走一次。

好办,我们把拆的点再连一个容量为inf,权值为0的点,代表可以多次走但不产生答案

关于连边,按两个关键字排序以后,从左往右只连接x递增而y递减的边。其实有点计算几何的影子


Code:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
const int N=4050;
const int M=400010;
const int inf=0xcfcfcfcf;
int head[N],edge[M],f[M],to[M],Next[M],cnt=1,t,ans;
void add(int u,int v,int w,int flow)
{
to[++cnt]=v;edge[cnt]=w;f[cnt]=flow;Next[cnt]=head[u];head[u]=cnt;
to[++cnt]=u;edge[cnt]=-w;f[cnt]=0;Next[cnt]=head[v];head[v]=cnt;
}
std::pair <int,int > dx[N>>1];
int n;
std::queue <int > q;
int dis[N],used[N],pre[N];
bool spfa()
{
memset(dis,0xcf,sizeof(dis));
dis[0]=0;
q.push(0);
while(!q.empty())
{
int u=q.front();
used[u]=0;
q.pop();
for(int i=head[u];i;i=Next[i])
{
int v=to[i],w=edge[i];
if(f[i]&&dis[v]<dis[u]+w)
{
dis[v]=dis[u]+w;
pre[v]=i;
if(!used[v])
{
used[v]=1;
q.push(v);
}
}
}
}
return dis[t]!=inf;
}
void augment()
{
ans+=dis[t];
int now=t;
while(now)
{
f[pre[now]^1]+=1;
f[pre[now]]-=1;
now=to[pre[now]^1];
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d%d",&dx[i].first,&dx[i].second);
std::sort(dx+1,dx+1+n);
for(int i=1;i<=n;i++)
{
int mi=-inf;
for(int j=i+1;j<=n;j++)
if(dx[j].second<mi&&dx[j].second>=dx[i].second)
{
add(i+n,j,0,-inf);
mi=dx[j].second;
}
}
t=n*2+2;
for(int i=1;i<=n;i++)
{
add(i,i+n,1,1);
add(i,i+n,0,-inf);
add(n*2+1,i,0,-inf);
add(i+n,t,0,-inf);
}
add(0,n*2+1,0,2);
while(spfa())
augment();
printf("%d\n",ans);
return 0;
}

2018.7.13

洛谷 P4066 [SHOI2003]吃豆豆 解题报告的更多相关文章

  1. 洛谷_Cx的故事_解题报告_第四题70

    1.并查集求最小生成树 Code: #include <stdio.h> #include <stdlib.h>   struct node {     long x,y,c; ...

  2. 洛谷 P3802 小魔女帕琪 解题报告

    P3802 小魔女帕琪 题目背景 从前有一个聪明的小魔女帕琪,兴趣是狩猎吸血鬼. 帕琪能熟练使用七种属性(金.木.水.火.土.日.月)的魔法,除了能使用这么多种属性魔法外,她还能将两种以上属性组合,从 ...

  3. 洛谷 P2317 [HNOI2005]星际贸易 解题报告

    P2317 [HNOI2005]星际贸易 题目描述 输入输出格式 输入格式: 输出格式: 如果可以找到这样的方案,那么输出文件output.txt中包含两个整数X和Y.X表示贸易额,Y表示净利润并且两 ...

  4. 洛谷 P2606 [ZJOI2010]排列计数 解题报告

    P2606 [ZJOI2010]排列计数 题目描述 称一个\(1,2,...,N\)的排列\(P_1,P_2...,P_n\)是\(Magic\)的,当且仅当对所以的\(2<=i<=N\) ...

  5. 洛谷1303 A*B Problem 解题报告

    洛谷1303 A*B Problem 本题地址:http://www.luogu.org/problem/show?pid=1303 题目描述 求两数的积. 输入输出格式 输入格式: 两个数 输出格式 ...

  6. 洛谷 P4100 [HEOI2013]钙铁锌硒维生素 解题报告

    P4100 [HEOI2013]钙铁锌硒维生素 题目描述 银河队选手名单出来了!小林,作为特聘的营养师,将负责银河队选手参加 宇宙比赛的饮食. 众所周知,前往宇宙的某个星球,通常要花费好长好长的时间, ...

  7. 洛谷 P4074 [WC2013]糖果公园 解题报告

    P4074 [WC2013]糖果公园 糖果公园 树上待修莫队 注意一个思想,dfn序处理链的方法,必须可以根据类似异或的东西,然后根据lca分两种情况讨论 注意细节 Code: #include &l ...

  8. 洛谷 P2473 [SCOI2008]奖励关 解题报告

    P2473 [SCOI2008]奖励关 题目描述 你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关.在这个奖励关里,系统将依次随机抛出\(k\)次宝物,每次你都可以选择吃或者不吃(必须在抛出下一个宝 ...

  9. 洛谷 P2805 [NOI2009]植物大战僵尸 解题报告

    P2805 [NOI2009] 植物大战僵尸 题目描述 Plants vs. Zombies(PVZ)是最近十分风靡的一款小游戏.Plants(植物)和Zombies(僵尸)是游戏的主角,其中Plan ...

随机推荐

  1. Linux系统中Oracle11g数据库的安装与验证

    1.查看Linux系统的位数 2.下载Oracle10g数据库软件 https://blog.csdn.net/xiezuoyong/article/details/81197688 (需要注册Ora ...

  2. Java线程Run和Start的区别

    先上结论:run只是Thread里面的一个普通方法,start是启动线程的方法.何以见得呢?可以执行下面的代码看看run和start的区别: package com.basic.thread; /** ...

  3. jquery中国地图插件

    插件下载地址: http://www.17sucai.com/preview/1266961/2018-09-18/map/js/jsMap-1.1.0.min.js jsMap 项目介绍 这是一个功 ...

  4. leetcode-下一个排列

    下一个排列 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列). 必须原地修改,只允许使用额外 ...

  5. mac 安装配置使用nexus3.x

    一.nexus安装 前置条件 :已经安装了JDK 1:下载nexus(http://www.sonatype.com/download-oss-sonatype) 最新版本3.0,下载目录为/User ...

  6. Python3【基础】-表达式与运算符

    一.什么是表达式? 1+2*3就是一个表达式,这里的加号和乘号叫做运算符,1.2.3叫做操作数.1+2*3计算的结果是7,计算结果可以存到一个变量中,即:res = 1 + 2 * 3. 所谓的表达式 ...

  7. A Bug's Life(加权并查集)

    Description Background  Professor Hopper is researching the sexual behavior of a rare species of bug ...

  8. Python:列表操作总结

    一.创建一个列表 只要把逗号分隔的不同数据项使用方括号括起来即可 list1=['physics','chemistry',1997,2000] list2=[1,2,3,4,5,6,7] [注]:1 ...

  9. C#控制台应用程序

    使用C#创建控制台应用程序的基本步骤: (1)创建项目: (2)编辑C#源代码: (3)编译运行: 例题:在控制台输出“Hello world!”. 第一步:文件→新建→项目:选择“项目类型”为Vis ...

  10. 复利计算器Junit单元测试

    一.测试场景 测试模块 测试输入 预期结果 运行结果 bug跟踪 复利计算 (本金,利率,年限,次数) 终值     测试运算结果 (100,5,3,1) 115.76 115.76   测试输入负数 ...