传送门

深海机器人问题差不多……看到有的大佬是用dp过的,强无敌……

考虑一下,把每一个点拆点,分别是$A_i$和$B_i$,连一条容量为$inf$,费用为$0$的边,表示可以随便走。如果有石头,再连一条边,容量为$1$,费用为$1$,表示只能走一次,且有$1$的价值。然后套路的建一个超级源和超级汇之后跑一个最大费用流即可

至于如何输出方案,可以一遍$dfs$,每一次只选一条边,然后判断一下这条边被选的次数是否大于等于反向边的流量,如果是说明已经不能再选,然后去选别的边

  1. //minamoto
  2. #include<iostream>
  3. #include<cstdio>
  4. #include<cstring>
  5. #include<queue>
  6. #define inf 0x3f3f3f3f
  7. using namespace std;
  8. #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
  9. char buf[<<],*p1=buf,*p2=buf;
  10. inline int read(){
  11. #define num ch-'0'
  12. char ch;bool flag=;int res;
  13. while(!isdigit(ch=getc()))
  14. (ch=='-')&&(flag=true);
  15. for(res=num;isdigit(ch=getc());res=res*+num);
  16. (flag)&&(res=-res);
  17. #undef num
  18. return res;
  19. }
  20. char sr[<<],z[];int C=-,Z;
  21. inline void Ot(){fwrite(sr,,C+,stdout),C=-;}
  22. inline void print(int x){
  23. if(C><<)Ot();
  24. while(z[++Z]=x%+,x/=);
  25. while(sr[++C]=z[Z],--Z);
  26. }
  27. const int N=,M=;
  28. int ver[M],Next[M],head[N],edge[M],flow[M],tmp[M],tot=;
  29. int dis[N],disf[N],Pre[N],last[N],vis[N],maxflow=;
  30. int ans[N],m=;
  31. int id[][],mp[][];
  32. int n,p,q,s,t,num=;
  33. queue<int> Q;
  34. inline void add(int u,int v,int f,int e){
  35. ver[++tot]=v,Next[tot]=head[u],head[u]=tot,flow[tot]=f,edge[tot]=e;
  36. ver[++tot]=u,Next[tot]=head[v],head[v]=tot,flow[tot]=,edge[tot]=-e;
  37. }
  38. bool spfa(){
  39. memset(dis,0xef,sizeof(dis));
  40. Q.push(s),dis[s]=,disf[s]=inf,Pre[t]=-;
  41. while(!Q.empty()){
  42. int u=Q.front();Q.pop();vis[u]=;
  43. for(int i=head[u];i;i=Next[i]){
  44. int v=ver[i];
  45. if(flow[i]&&dis[v]<dis[u]+edge[i]){
  46. dis[v]=dis[u]+edge[i],last[v]=i,Pre[v]=u;
  47. disf[v]=min(disf[u],flow[i]);
  48. if(!vis[v]) vis[v]=,Q.push(v);
  49. }
  50. }
  51. }
  52. return ~Pre[t];
  53. }
  54. void dinic(){
  55. while(spfa()){
  56. int u=t;maxflow+=disf[t];
  57. while(u!=s){
  58. flow[last[u]]-=disf[t];
  59. flow[last[u]^]+=disf[t];
  60. u=Pre[u];
  61. }
  62. }
  63. }
  64. void dfs(int x,int y){
  65. int now=id[x][y],d0=id[x+][y],d1=id[x][y+];
  66. for(int i=head[now+num];i;i=Next[i]){
  67. if(tmp[i]>=flow[i^]) continue;
  68. if(ver[i]==d0){
  69. ++tmp[i],ans[++m]=;
  70. dfs(x+,y);
  71. return;
  72. }
  73. if(ver[i]==d1){
  74. ++tmp[i],ans[++m]=;
  75. dfs(x,y+);
  76. return;
  77. }
  78. }
  79. }
  80. int main(){
  81. n=read(),q=read(),p=read();
  82. for(int i=;i<=p;++i)
  83. for(int j=;j<=q;++j)
  84. id[i][j]=++num;
  85. s=,t=num*+;
  86. for(int i=;i<=p;++i)
  87. for(int j=;j<=q;++j)
  88. mp[i][j]=read();
  89. add(s,id[][],n,),add(id[p][q],t,n,);
  90. for(int i=;i<=p;++i)
  91. for(int j=;j<=q;++j){
  92. if(mp[i][j]&) continue;
  93. add(id[i][j],id[i][j]+num,inf,);
  94. if(mp[i][j]) add(id[i][j],id[i][j]+num,,);
  95. }
  96. for(int i=;i<=p;++i)
  97. for(int j=;j<=q;++j){
  98. if(mp[i][j]&) continue;
  99. if(i<p&&mp[i+][j]!=) add(id[i][j]+num,id[i+][j],inf,);
  100. if(j<q&&mp[i][j+]!=) add(id[i][j]+num,id[i][j+],inf,);
  101. }
  102. dinic();
  103. for(int i=;i<=maxflow;++i){
  104. m=,dfs(,);
  105. for(int j=;j<=m;++j) print(i),sr[++C]=' ',print(ans[j]),sr[++C]='\n';
  106. }
  107. Ot();
  108. return ;
  109. }

洛谷P3356 火星探险问题(费用流)的更多相关文章

  1. 洛谷P3356 火星探险问题(费用流)

    题目描述 火星探险队的登陆舱将在火星表面着陆,登陆舱内有多部障碍物探测车.登陆舱着陆后,探测车将离开登陆舱向先期到达的传送器方向移动.探测车在移动中还必须采集岩石标本.每一块岩石标本由最先遇到它的探测 ...

  2. 洛谷 P3356 火星探险问题 【最大费用最大流】

    输出方案好麻烦啊 拆点,石头的连(i,i',1,1)(i,i',inf,0)表示可以取一次价值1,空地直接连(i,i',inf,0),对于能走到的两个格子(不包括障碍),连接(i',j,inf,0), ...

  3. 洛谷 1004 dp或最大费用流

    思路: dp方法: 设dp[i][j][k][l]为两条没有交叉的路径分别走到(i,j)和(k,l)处最大价值. 则转移方程为 dp[i][j][k][l]=max(dp[i-1][j][k-1][l ...

  4. 洛谷P4003 无限之环(费用流)

    传送门 神仙题啊……不看题解我可能一年都不一定做得出来……FlashHu大佬太强啦 到底是得有怎样的脑回路才能一眼看去就是费用流啊…… 建好图之后套个板子就好了,那么我们着重来讨论一下怎么建图 首先, ...

  5. 洛谷P4012 深海机器人问题(费用流)

    题目描述 深海资源考察探险队的潜艇将到达深海的海底进行科学考察. 潜艇内有多个深海机器人.潜艇到达深海海底后,深海机器人将离开潜艇向预定目标移动. 深海机器人在移动中还必须沿途采集海底生物标本.沿途生 ...

  6. 洛谷P2517 HAOI2010 订货 (费用流)

    标准的费用流问题,关键在于巧妙地建模 一共有n个月份,源点设为0,汇点设为n+1 1.源点向所有月份连边,容量为正无穷,费用为该月进货的费用 2.每个月向下一个月连边,容量为仓库容量,费用为存货费用 ...

  7. 洛谷P4016 负载平衡问题 费用流

    这道题还是很好的. 考察了选手对网络流的理解. 首先,任意两个相邻点之间的运货量时没有限制的. 我们可以将相邻点之间的流量建为无限大,单位费用设为 1,代表运输一个货物需耗费一个代价. 由于题目要求最 ...

  8. 洛谷.1251.餐巾计划问题(费用流SPFA)

    题目链接 /* 每一天的餐巾需求相当于必须遍历某些点若干次 设q[i]为Dayi需求量 (x,y)表示边x容y费 将每个点i拆成i,i',由i'->T连(q[i],0)的边,表示求最大流的话一定 ...

  9. 洛谷P2770 航空路线问题(费用流)

    题意 $n$个点从左向右依次排列,有$m$条双向道路 问从起点到终点,再从终点回到起点,在经过的点不同的情况下最多能经过几个点 Sol 首先,问题可以转化为求两条互不相交的路径,使得点数最多 为了满足 ...

随机推荐

  1. 程序实现DataGrid过滤设置

    给gdv_pro.ActiveFilterString赋值就能直接控制DataGrid过滤 gdv_pro.ActiveFilterString语法: 最简单方式:gdv_pro.ActiveFilt ...

  2. LeetCode题解 #2 Add Two Numbers

    题目大意:使用链表表示的两个整数,计算出其和,以同样的形式返回. Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) Output: 7 -> 0 ...

  3. How To Install Git on CentOS 7

    Introduction Version control has become an indispensable tool in modern software development. Versio ...

  4. C++虚函数与纯虚函数用法与区别(转载)

    1. 虚函数和纯虚函数可以定义在同一个类(class)中,含有纯虚函数的类被称为抽象类(abstract class),而只含有虚函数的类(class)不能被称为抽象类(abstract class) ...

  5. 【原创】8. MYSQL++中的Row类型

    一.mysqlpp::Row类型 在之前的介绍中我们看到了如何通过mysqlpp::Query找到各种Result类型,然后又仔细分析了各种Result类型又是如何生成对应的Row类型(如下所示). ...

  6. eclipse生成的web项目在resin服务器上的发布(不能解析web.xml)

    首先报错误: web项目web.xml文件如下: <?xml version="1.0" encoding="UTF-8"?> <web-ap ...

  7. eclipse检测不到android的手机

    eclipse检测不到android设备我们一般重启adb server但是一般不管用,下面是重启adb server adb kill-server 可能出现“服务没有运行”的提示信息如下: * s ...

  8. 2-配置Andriod环境时的错误。。。Theme.AppCompat.Light

    编译或运行时可能会出现错误: Error:Error retrieving parent for item: No resource found that matches the given name ...

  9. 框架面试题:谈谈我对Spring IOC与DI的理解

    IOC是一种叫做“控制反转”的设计思想. 1.较浅的层次——从名字上解析 “控制”就是指对 对象的创建.维护.销毁等生命周期的控制,这个过程一般是由我们的程序去主动控制的,如使用new关键字去创建一个 ...

  10. PCL 编程多个点云合成

    博客转载自:https://blog.csdn.net/sunboyiris/article/details/72636809 pcl::PointCloud<pcl::PointXYZRGBA ...