如果你知道他是网络流的话你就很快会想到一个最大费用最大流的模型,然后你发现可能T,然而你发现你只用增广两次,然后你就开心的打了出来,然后发现被稠密图里spfa的丧病时间复杂度坑了,还是会T。于是我就开始找优化方式,一开始我想优化边数,可是发现,不会,然后我就开始瞎搞。我把第一遍spfa改成了最长上升子序列,第二遍是在第一遍的基础上建的图,由于没有反向边所以快了许多,然后就过了,高兴。我去看了看题解里面说的是优化边数,它的思路就是把一个边拆开,就是说,我们原来连边都是从前往后从低向高连(如果按照x排序的话),那么我们把两个点之间的边拆成最小,就是说,连边的两点之间不会有高度在其之间的点,虽然说这样连边仍然有可能把边数卡到百万级别但是会好很多,就是要注意这样做的话必须要让拆开的点之间连Inf流量以支持交通运输,所以我就把这两个东西结合了一下。
这道题的启发在于对于一些并不像网络流的东西进行网络流,以及通过观察特点来更加准确的估算时间复杂度以不至于做出错误判断,还有就是替换算法来提高时间效率,最重要的一点当然就是优化边数的方法,就是把各个边等效化同时增加一些边的功能以减少边数,换言之就是把边拆分,更准确的说就是找到基底。

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. const int N=;
  5. const int Inf=0x3f3f3f3f;
  6. const int oo=0xafafafaf;
  7. struct V{
  8. int to,next,c;
  9. }c[N*N/];
  10. int head[N*],t;
  11. inline void add(int x,int y,int z){
  12. c[++t].to=y,c[t].next=head[x],head[x]=t,c[t].c=z;
  13. }
  14. int dis[N*];
  15. int cnt[N],anc[N];
  16. int q[N*],front,back;
  17. bool in[N*];
  18. bool via[*N][*N];
  19. int n;
  20. int S,T,tail;
  21. struct Point{
  22. int x,y;
  23. }poi[N];
  24. inline bool comp(Point a,Point b){
  25. return a.x<b.x||(a.x==b.x&&a.y<b.y);
  26. }
  27. inline void spfa(){
  28. memset(dis,0xaf,sizeof(dis));
  29. q[back++]=S,dis[S]=,in[S]=true;
  30. if(back==(N<<))back=;
  31. while(front!=back){
  32. int x=q[front++];in[x]=false;
  33. if(front==(N<<))front=;
  34. for(int i=head[x];i;i=c[i].next)
  35. if(dis[x]+c[i].c>dis[c[i].to]){
  36. dis[c[i].to]=dis[x]+c[i].c;
  37. if(!in[c[i].to]){
  38. q[back++]=c[i].to,in[c[i].to]=true;
  39. if(back==(N<<))back=;
  40. }
  41. }
  42. }
  43. }
  44. int main(){
  45. scanf("%d",&n);
  46. if(n==){
  47. printf("");
  48. return ;
  49. }
  50. if(n==){
  51. printf("");
  52. return ;
  53. }
  54. int ans=;
  55. S=n+n+,T=n+n+;
  56. for(int i=;i<=n;++i)
  57. scanf("%d%d",&poi[i].x,&poi[i].y);
  58. std::sort(poi+,poi+n+,comp);
  59. for(int i=;i<=n;++i){
  60. cnt[i]=,anc[i]=;
  61. for(int j=i-;j>;--j)
  62. if(poi[j].y<=poi[i].y&&cnt[i]<cnt[j]+)
  63. cnt[i]=cnt[j]+,anc[i]=j;
  64. if(cnt[i]>ans)
  65. ans=cnt[i],tail=i;
  66. }
  67. int last=T;
  68. for(int i=tail;i;i=anc[i]){
  69. via[i][i+n]=true;
  70. via[i+n][last]=true;
  71. add(last,i+n,);
  72. add(i+n,i,-);
  73. last=i;
  74. }
  75. via[S][last]=true;
  76. add(last,S,);
  77. for(int i=;i<=n;++i){
  78. add(S,i,);
  79. add(i+n,T,);
  80. if(via[i][i+n]==false)add(i,i+n,);
  81. add(i,i+n,);
  82. for(int j=i+,min=Inf;j<=n;++j)
  83. if(poi[j].y>=poi[i].y&&poi[j].y<min)
  84. add(i+n,j,),min=poi[j].y;
  85. }
  86. spfa(),ans+=dis[T];
  87. printf("%d",ans);
  88. return ;
  89. }

结合的优秀代码

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. const int N=;
  5. const int Inf=0x3f3f3f3f;
  6. const int oo=0xafafafaf;
  7. struct V{
  8. int to,next,f,c;
  9. }c[N*N];
  10. int head[N*],t=;
  11. inline void add(int x,int y,int z,int _){
  12. c[++t].to=y,c[t].next=head[x],head[x]=t,c[t].f=z,c[t].c=_;
  13. }
  14. int dis[N*],anc[N*];
  15. int q[N*],front,back;
  16. bool in[N*];
  17. int n;
  18. int S,T,source;
  19. struct Point{
  20. int x,y;
  21. }poi[N];
  22. inline bool look(Point a,Point b){
  23. return b.x>=a.x&&b.y>=a.y;
  24. }
  25. inline bool comp(Point a,Point b){
  26. return a.x<b.x||(a.x==b.x&&a.y<b.y);
  27. }
  28. inline bool spfa(){
  29. memset(dis,0xaf,sizeof(dis));
  30. q[back++]=S,dis[S]=,in[S]=true;
  31. if(back==(N<<))back=;
  32. while(front!=back){
  33. int x=q[front++];in[x]=false;
  34. if(front==(N<<))front=;
  35. for(int i=head[x];i;i=c[i].next)
  36. if(c[i].f&&dis[x]+c[i].c>dis[c[i].to]){
  37. dis[c[i].to]=dis[x]+c[i].c,anc[c[i].to]=i;
  38. if(!in[c[i].to]){
  39. q[back++]=c[i].to,in[c[i].to]=true;
  40. if(back==(N<<))back=;
  41. }
  42. }
  43. }
  44. return dis[T]!=oo;
  45. }
  46. inline int shoot(){
  47. int f=Inf;
  48. for(int i=anc[T];i;i=anc[c[i^].to])f=std::min(f,c[i].f);
  49. for(int i=anc[T];i;i=anc[c[i^].to])c[i].f-=f,c[i^].f+=f;
  50. return f*dis[T];
  51. }
  52. int main(){
  53. scanf("%d",&n);
  54. source=n+n+,S=n+n+,T=n+n+;
  55. add(S,source,,),add(source,S,,);
  56. for(int i=;i<=n;++i)
  57. scanf("%d%d",&poi[i].x,&poi[i].y);
  58. std::sort(poi+,poi+n+,comp);
  59. for(int i=;i<=n;++i){
  60. add(source,i,Inf,),add(i,source,,);
  61. add(i+n,T,Inf,),add(T,i+n,,);
  62. add(i,i+n,,),add(i+n,i,,-);
  63. add(i,i+n,Inf,),add(i+n,i,,);
  64. for(int j=i+,min=Inf;j<=n;++j)
  65. if(poi[j].y>=poi[i].y&&poi[j].y<min)
  66. add(i+n,j,Inf,),add(j,i+n,,),min=poi[j].y;
  67. }
  68. int ans=;
  69. while(spfa())ans+=shoot();
  70. printf("%d",ans);
  71. return ;
  72. }

质朴的边优化费用流

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

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

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

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

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

  3. 1930: [Shoi2003]pacman 吃豆豆

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

  4. BZOJ1930 [Shoi2003]pacman 吃豆豆

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

  5. [bzoj]1930 pacman吃豆豆

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

  6. 【BZOJ1930】【SHOI2003】吃豆豆

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

  7. BZOJ 3876 [AHOI/JSOI2014]支线剧情 (最小费用可行流)

    题面:洛谷传送门 BZOJ传送门 题目大意:给你一张有向无环图,边有边权,让我们用任意条从1号点开始的路径覆盖这张图,需要保证覆盖完成后图内所有边都被覆盖至少一次,求覆盖路径总长度的最小值 最小费用可 ...

  8. bzoj 1877 [SDOI2009]晨跑(最小费用最大流)

    Description Elaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧撑.仰卧起坐等 等,不过到目前为止,他坚持下来的只有晨跑. 现在给出一张学校附近的地图,这张地图中包含N个十 ...

  9. bzoj 1927 [Sdoi2010]星际竞速(最小费用最大流)

    1927: [Sdoi2010]星际竞速 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 1576  Solved: 954[Submit][Statu ...

随机推荐

  1. libpng的使用

    zlib 适用于数据压缩的函式库,由Jean-loup Gailly (负责compression)和 Mark Adler (负责decompression)开发. zlib被设计成一个免费的.通用 ...

  2. ATM购物车程序项目规范(更新到高级版)

    ATM购物车程序(高级版) 之前的低级版本已经删除,现在的内容太多,没时间把内容上传,有时间我会把项目源码奉上! 我已经把整个项目源码传到群文件里了,需要的可以加主页qq群号.同时群内也有免费的学习资 ...

  3. 让CPU使用率正弦变化

    网络上流传一个面试题,说如何编程让CPU的使用率按照正弦方式变化 代码如下(运行环境Linux): #include <stdio.h> #include <stdlib.h> ...

  4. class实现Stack

    基于class实现一个存储string类型的Stack 头文件: //stack.h #include<vector> #include<string> class Stack ...

  5. 基于vue来开发一个仿饿了么的外卖商城(二)

    一.抽出头部作为一个组件,在底部导航的时候可以相应的显示不同的标题 技术点:使用slot进行组件间的通信:父组件给子组件传值(子组件里面通过props接收父组件传过来的数据) 查看链接:https:/ ...

  6. (数据科学学习手札17)线性判别分析的原理简介&Python与R实现

    之前数篇博客我们比较了几种具有代表性的聚类算法,但现实工作中,最多的问题是分类与定性预测,即通过基于已标注类型的数据的各显著特征值,通过大量样本训练出的模型,来对新出现的样本进行分类,这也是机器学习中 ...

  7. ajax同步和异步的切换

    ajax为网页提供了非常不错的异步机制,但是有时候两个ajax放在一起,希望第一个完成后再继续第二个ajax的执行.这时候可以将第一个ajax代码带上同步参数即可,如下: $.ajax({ async ...

  8. Mac系统下安装Homebrew后无法使用brew命令,-bash: brew: command not found

    使用如下命令: sudo vim .bash_profile 然后输入以下代码: export PATH=/usr/local/bin:$PATH 再使用以下命令使配置生效: source .bash ...

  9. stm32--FatFs移植(SPIFlash)

    前言 硬件: 单片机:stm32f072CB,sram大小16k.(其他单片机只要sram>8k即可通用) SPIFlash:W25Q128FV,16Mbyte,单次擦除最小4k. 程序使用Ke ...

  10. 【WPF】 布局篇

    [WPF] 布局篇 一. 几个常用且至关重要的属性 1. Width,Height : 设置窗体,控件宽高. 这里注意,WPF是自适应的, 所以把这2个属性设置 Auto, 则控件宽高会自动改变. 2 ...