方格取数的升级版,每个格子最多取一次。

$k=1$的话就是个普及组的dp题,$k=2$就是在之前的基础上多加两维。

然而现在$k$太大了当然就不dp啦

对于$k=1$的情况我们还可以把$(i,j)$向$(i+1,j),(i,j+1)$连边然后答案就是跑最长路,而对于更大的情况我们的瓶颈在于直接跑最长路不能限制每个点只取一次。

对于点来说没有什么好的方法我们就把问题转移到边上:把每个点拆成一条边。具体的说就是把一个点拆成两个点,把点权变成边权,而我们又要限制这样子的每条边最多走一次,这里就有点费用流的感觉了(雾)。

所以我们可以这样建图:把点$i$拆成$i$和$i'$,不妨令$i$为入点$i'$为出点,从入点到出点连两条边:一条容量为1,费用为点权$c$,另一条容量为$k-1$,费用为0。

原图里的点的出点再向能够直接到达的点的入点连一条容量为$k$,费用为0的边。

这样每次bfs的时候只要成功都会走出一条完整的路径,路径上的费用被算进去之后这条路也就不会再走了(因为有费用的只有容量为1的嘛),于是也就保证了只会取一次并且一定是第一次经过的时候被取走。

以起点的入点为源点,以终点的出点为汇点跑最大费用最大流得到的就是答案啦

  1. #include<cstdio>
  2. #include<queue>
  3. #include<cstring>
  4. #define rep(i,n) for(register int i=1;i<=n;i++)
  5. #define REP(i,a,b) for(reigster int i=a;i<=b;i++)
  6. using namespace std;
  7. const int N=5005;
  8. const int M=20005;
  9. const int INF=(~0u>>1);
  10. struct edge
  11. {
  12. int to,nxt,w,c;
  13. edge(int to=0,int nxt=0,int w=0,int c=0):to(to),nxt(nxt),w(w),c(c){}
  14. }edges[M<<1];
  15. int n,k,s,t,ans,cnt;
  16. int head[M<<1],infc[N],vis[N],d[N],pre[N];
  17. queue<int>q;
  18.  
  19. inline void addEdge(int u,int v,int w,int c)
  20. {
  21. edges[++cnt]=edge(v,head[u],w,c);head[u]=cnt;
  22. edges[++cnt]=edge(u,head[v],0,-c);head[v]=cnt;
  23. }
  24. inline int get_num(int i,int j,int p)
  25. {
  26. return (i-1)*n+j+n*n*p;
  27. }
  28. #define cur edges[i].to
  29. inline bool spfa()
  30. {
  31. memset(vis,0,sizeof vis);
  32. rep(i,t)d[i]=-INF;q.push(s);
  33. d[s]=0;infc[s]=INF;vis[s]=1;
  34. while(!q.empty())
  35. {
  36. int x=q.front();q.pop();vis[x]=0;
  37. for(register int i=head[x];i;i=edges[i].nxt)if(edges[i].w&&d[cur]<d[x]+edges[i].c)
  38. {
  39. d[cur]=d[x]+edges[i].c;
  40. pre[cur]=i;infc[cur]=min(infc[x],edges[i].w);
  41. if(!vis[cur])vis[cur]=1,q.push(cur);
  42. }
  43. }
  44. if(d[t]==-INF)return 0;
  45. return 1;
  46. }
  47. #undef cur
  48. inline void updata()
  49. {
  50.  
  51. int tmp=t;
  52. while(tmp!=s)
  53. {
  54. int i=pre[tmp];
  55. edges[i].w-=infc[t];
  56. edges[i^1].w+=infc[t];
  57. tmp=edges[i^1].to;
  58. }
  59. ans+=d[t];
  60. }
  61. int main()
  62. {
  63. scanf("%d%d",&n,&k);
  64. s=1;t=2*n*n;cnt=1;
  65. rep(i,n)rep(j,n)
  66. {
  67. int x;scanf("%d",&x);
  68. addEdge(get_num(i,j,0),get_num(i,j,1),1,x);
  69. addEdge(get_num(i,j,0),get_num(i,j,1),k-1,0);
  70. if(i<n)addEdge(get_num(i,j,1),get_num(i+1,j,0),k,0);
  71. if(j<n)addEdge(get_num(i,j,1),get_num(i,j+1,0),k,0);
  72. }
  73. while(spfa())updata();
  74. printf("%d",ans);
  75. return 0;
  76. }

[日常摸鱼]pojKaka's Matrix Travels-拆点+最大费最大流的更多相关文章

  1. [日常摸鱼]bzoj2724蒲公英-分块

    区间众数经典题~ http://begin.lydsy.com/JudgeOnline/problem.php?id=4839这里可以提交~ 题意大概就是没有修改的询问区间众数,如果有一样的输出最小的 ...

  2. [日常摸鱼]bzoj2875[NOI2012]随机数生成器-矩阵快速幂

    好裸的矩阵快速幂-然而我一开始居然构造不出矩阵- 平常两个的情况都是拿相邻两项放在矩阵里拿去递推的-然后我就一直构造不出来-其实把矩阵下面弄成1就好了啊orz #include<cstdio&g ...

  3. [日常摸鱼]HDU2157 How many ways??

    hhh我又开始水题目了 题意:给一张有向图,多次询问一个点到另一个点刚好走$k$步的方案数取模,点数很小 每个$a,b,k$的询问直接把邻接矩阵$map$自乘$k$次后$map[a][b]$就是答案了 ...

  4. [日常摸鱼]poj2778 DNA Sequence

    这题太神啦 题意:求长度为$n$的不包含给定DNA序列的DNA序列个数,给定的不超过10个 构建出Trie图,用$danger[i]$来表示不能走到$i$,对于DNA序列结尾的结点$danger$设为 ...

  5. [日常摸鱼]bzoj1444 [JSOI2009]有趣的游戏——AC自动机+矩阵

    今天学校跳蚤市场摆摊聚众吸毒打call,东西卖了一百多好开心_(:з」∠)_ (然后大家中午就去吃了一顿好的x) 下午听演讲然后现在来填坑orz(其实是昨晚的坑) 题目:bzoj1444 先用字符串构 ...

  6. Hash 日常摸鱼笔记

    本篇文章是Hash在信息学竞赛中的应用的学习笔记,分多次更新(已经有很多坑了) 一维递推 首先是Rabin-Karp,对于一个长度为\(m\)的串\(S\) \(f(S)=\sum_{i=1}^{m} ...

  7. [日常摸鱼]HDU1724 Ellipse-自适应Simpson法

    模板题~ QAQ话说Simpson法的原理我还是不太懂-如果有懂的dalao麻烦告诉我~ 题意:每次给一个椭圆的标准方程,求夹在直线$x=l$和$x=r$之间的面积 Simpson法 (好像有时候也被 ...

  8. [日常摸鱼]bzoj1257余数之和

    题意:输入$k,n$,求$\sum_{i=1}^n k \mod i$ $k \mod i=k-i*\lfloor \frac{k}{i} \rfloor $,$n$个$k$直接求和,后面那个东西像比 ...

  9. [日常摸鱼]bzoj1001狼抓兔子-最大流最小割

    题意就是求最小割- 然后我们有这么一个定理(最大流-最小割定理 ): 任何一个网络图的最小割中边的容量之和等于图的最大流. (下面直接简称为最大流和最小割) 证明: 如果最大流>最小割,那把这些 ...

随机推荐

  1. [COCI2016-2017#1] Mag

    [COCI2016-2017#1] Mag 题解 题目TP门 题目描述 你将获得一棵由无向边连接的树.树上每个节点都有一个魔力值. 我们定义,一条路径的魔力值为路径上所有节点魔力值的乘积除以路径上的节 ...

  2. MathType总结编辑括号的类型(上)

    括号的种类有很多,我们用得也很多,可以说无处不见,不只是在数学物理这些自然科学的公式中来断地出现括号,即使是在人文艺术类的领域也会有括号的出现.下面就和小编一起来看看公式编辑器编辑括号的类型吧! Ma ...

  3. js 手机号验证

    1 js 通过正则表达式对手机号进行验证 2 3 var reg = /^1[3|4|5|8][0-9]\d{4,8}$/; 4 var sMobile = document.mobileform.m ...

  4. Java基础教程——线程池

    启动新线程,需要和操作系统进行交互,成本比较高. 使用线程池可以提高性能-- 线程池会提前创建大量的空闲线程,随时待命执行线程任务.在执行完了一个任务之后,线程会回到空闲状态,等待执行下一个任务.(这 ...

  5. @Transactional自调用问题

  6. PADS生成贴片文件

    PADS生成贴片文件 VIEW-BOTTOM VIEW能够使Bottom层正常显示. 1. pastmask_top->Output Devices->Device Setup- 2. 进 ...

  7. 【GDOI2007】JZOJ2020年8月10日提高组T1 夏娜的菠萝包

    [GDOI2007]JZOJ2020年8月10日提高组T1 夏娜的菠萝包 题目 Description 夏娜很喜欢吃菠萝包,她的经纪人RC每半个月就要为她安排接下来的菠萝包计划.今天是7月份,RC又要 ...

  8. 老猿学5G专栏文章目录

    ☞ ░ 前往老猿Python博文目录 ░ 一.3GPP规范文档及其他推荐阅读博文 老猿学5G扫盲贴:3GPP规范文档命名规则及同系列文档阅读指南 老猿学5G扫盲贴:3GPP规范中部分与计费相关的规范序 ...

  9. PyQt(Python+Qt)学习随笔:containers容器类部件QStackedWidget重要方法介绍

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 StackedWidget堆叠窗口部件为一系列窗口部件的堆叠,对应类为QStackedWidget. ...

  10. OLLVM简单入门

    目前市面上的许多安全公司都会在保护IOS应用程序或安卓APP时都会用到OLLVM技术.譬如说顶象IOS加固.网易IOS加固等等.故而我们今天研究下OLLVM是个什么.将从(1)OLLVM是什么?OLL ...