洛谷P3356 火星探险问题(费用流)
和深海机器人问题差不多……看到有的大佬是用dp过的,强无敌……
考虑一下,把每一个点拆点,分别是$A_i$和$B_i$,连一条容量为$inf$,费用为$0$的边,表示可以随便走。如果有石头,再连一条边,容量为$1$,费用为$1$,表示只能走一次,且有$1$的价值。然后套路的建一个超级源和超级汇之后跑一个最大费用流即可
至于如何输出方案,可以一遍$dfs$,每一次只选一条边,然后判断一下这条边被选的次数是否大于等于反向边的流量,如果是说明已经不能再选,然后去选别的边
- //minamoto
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- #include<queue>
- #define inf 0x3f3f3f3f
- using namespace std;
- #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
- char buf[<<],*p1=buf,*p2=buf;
- inline int read(){
- #define num ch-'0'
- char ch;bool flag=;int res;
- while(!isdigit(ch=getc()))
- (ch=='-')&&(flag=true);
- for(res=num;isdigit(ch=getc());res=res*+num);
- (flag)&&(res=-res);
- #undef num
- return res;
- }
- char sr[<<],z[];int C=-,Z;
- inline void Ot(){fwrite(sr,,C+,stdout),C=-;}
- inline void print(int x){
- if(C><<)Ot();
- while(z[++Z]=x%+,x/=);
- while(sr[++C]=z[Z],--Z);
- }
- const int N=,M=;
- int ver[M],Next[M],head[N],edge[M],flow[M],tmp[M],tot=;
- int dis[N],disf[N],Pre[N],last[N],vis[N],maxflow=;
- int ans[N],m=;
- int id[][],mp[][];
- int n,p,q,s,t,num=;
- queue<int> Q;
- inline void add(int u,int v,int f,int e){
- ver[++tot]=v,Next[tot]=head[u],head[u]=tot,flow[tot]=f,edge[tot]=e;
- ver[++tot]=u,Next[tot]=head[v],head[v]=tot,flow[tot]=,edge[tot]=-e;
- }
- bool spfa(){
- memset(dis,0xef,sizeof(dis));
- Q.push(s),dis[s]=,disf[s]=inf,Pre[t]=-;
- while(!Q.empty()){
- int u=Q.front();Q.pop();vis[u]=;
- for(int i=head[u];i;i=Next[i]){
- int v=ver[i];
- if(flow[i]&&dis[v]<dis[u]+edge[i]){
- dis[v]=dis[u]+edge[i],last[v]=i,Pre[v]=u;
- disf[v]=min(disf[u],flow[i]);
- if(!vis[v]) vis[v]=,Q.push(v);
- }
- }
- }
- return ~Pre[t];
- }
- void dinic(){
- while(spfa()){
- int u=t;maxflow+=disf[t];
- while(u!=s){
- flow[last[u]]-=disf[t];
- flow[last[u]^]+=disf[t];
- u=Pre[u];
- }
- }
- }
- void dfs(int x,int y){
- int now=id[x][y],d0=id[x+][y],d1=id[x][y+];
- for(int i=head[now+num];i;i=Next[i]){
- if(tmp[i]>=flow[i^]) continue;
- if(ver[i]==d0){
- ++tmp[i],ans[++m]=;
- dfs(x+,y);
- return;
- }
- if(ver[i]==d1){
- ++tmp[i],ans[++m]=;
- dfs(x,y+);
- return;
- }
- }
- }
- int main(){
- n=read(),q=read(),p=read();
- for(int i=;i<=p;++i)
- for(int j=;j<=q;++j)
- id[i][j]=++num;
- s=,t=num*+;
- for(int i=;i<=p;++i)
- for(int j=;j<=q;++j)
- mp[i][j]=read();
- add(s,id[][],n,),add(id[p][q],t,n,);
- for(int i=;i<=p;++i)
- for(int j=;j<=q;++j){
- if(mp[i][j]&) continue;
- add(id[i][j],id[i][j]+num,inf,);
- if(mp[i][j]) add(id[i][j],id[i][j]+num,,);
- }
- for(int i=;i<=p;++i)
- for(int j=;j<=q;++j){
- if(mp[i][j]&) continue;
- if(i<p&&mp[i+][j]!=) add(id[i][j]+num,id[i+][j],inf,);
- if(j<q&&mp[i][j+]!=) add(id[i][j]+num,id[i][j+],inf,);
- }
- dinic();
- for(int i=;i<=maxflow;++i){
- m=,dfs(,);
- for(int j=;j<=m;++j) print(i),sr[++C]=' ',print(ans[j]),sr[++C]='\n';
- }
- Ot();
- return ;
- }
洛谷P3356 火星探险问题(费用流)的更多相关文章
- 洛谷P3356 火星探险问题(费用流)
题目描述 火星探险队的登陆舱将在火星表面着陆,登陆舱内有多部障碍物探测车.登陆舱着陆后,探测车将离开登陆舱向先期到达的传送器方向移动.探测车在移动中还必须采集岩石标本.每一块岩石标本由最先遇到它的探测 ...
- 洛谷 P3356 火星探险问题 【最大费用最大流】
输出方案好麻烦啊 拆点,石头的连(i,i',1,1)(i,i',inf,0)表示可以取一次价值1,空地直接连(i,i',inf,0),对于能走到的两个格子(不包括障碍),连接(i',j,inf,0), ...
- 洛谷 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 ...
- 洛谷P4003 无限之环(费用流)
传送门 神仙题啊……不看题解我可能一年都不一定做得出来……FlashHu大佬太强啦 到底是得有怎样的脑回路才能一眼看去就是费用流啊…… 建好图之后套个板子就好了,那么我们着重来讨论一下怎么建图 首先, ...
- 洛谷P4012 深海机器人问题(费用流)
题目描述 深海资源考察探险队的潜艇将到达深海的海底进行科学考察. 潜艇内有多个深海机器人.潜艇到达深海海底后,深海机器人将离开潜艇向预定目标移动. 深海机器人在移动中还必须沿途采集海底生物标本.沿途生 ...
- 洛谷P2517 HAOI2010 订货 (费用流)
标准的费用流问题,关键在于巧妙地建模 一共有n个月份,源点设为0,汇点设为n+1 1.源点向所有月份连边,容量为正无穷,费用为该月进货的费用 2.每个月向下一个月连边,容量为仓库容量,费用为存货费用 ...
- 洛谷P4016 负载平衡问题 费用流
这道题还是很好的. 考察了选手对网络流的理解. 首先,任意两个相邻点之间的运货量时没有限制的. 我们可以将相邻点之间的流量建为无限大,单位费用设为 1,代表运输一个货物需耗费一个代价. 由于题目要求最 ...
- 洛谷.1251.餐巾计划问题(费用流SPFA)
题目链接 /* 每一天的餐巾需求相当于必须遍历某些点若干次 设q[i]为Dayi需求量 (x,y)表示边x容y费 将每个点i拆成i,i',由i'->T连(q[i],0)的边,表示求最大流的话一定 ...
- 洛谷P2770 航空路线问题(费用流)
题意 $n$个点从左向右依次排列,有$m$条双向道路 问从起点到终点,再从终点回到起点,在经过的点不同的情况下最多能经过几个点 Sol 首先,问题可以转化为求两条互不相交的路径,使得点数最多 为了满足 ...
随机推荐
- 程序实现DataGrid过滤设置
给gdv_pro.ActiveFilterString赋值就能直接控制DataGrid过滤 gdv_pro.ActiveFilterString语法: 最简单方式:gdv_pro.ActiveFilt ...
- LeetCode题解 #2 Add Two Numbers
题目大意:使用链表表示的两个整数,计算出其和,以同样的形式返回. Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) Output: 7 -> 0 ...
- How To Install Git on CentOS 7
Introduction Version control has become an indispensable tool in modern software development. Versio ...
- C++虚函数与纯虚函数用法与区别(转载)
1. 虚函数和纯虚函数可以定义在同一个类(class)中,含有纯虚函数的类被称为抽象类(abstract class),而只含有虚函数的类(class)不能被称为抽象类(abstract class) ...
- 【原创】8. MYSQL++中的Row类型
一.mysqlpp::Row类型 在之前的介绍中我们看到了如何通过mysqlpp::Query找到各种Result类型,然后又仔细分析了各种Result类型又是如何生成对应的Row类型(如下所示). ...
- eclipse生成的web项目在resin服务器上的发布(不能解析web.xml)
首先报错误: web项目web.xml文件如下: <?xml version="1.0" encoding="UTF-8"?> <web-ap ...
- eclipse检测不到android的手机
eclipse检测不到android设备我们一般重启adb server但是一般不管用,下面是重启adb server adb kill-server 可能出现“服务没有运行”的提示信息如下: * s ...
- 2-配置Andriod环境时的错误。。。Theme.AppCompat.Light
编译或运行时可能会出现错误: Error:Error retrieving parent for item: No resource found that matches the given name ...
- 框架面试题:谈谈我对Spring IOC与DI的理解
IOC是一种叫做“控制反转”的设计思想. 1.较浅的层次——从名字上解析 “控制”就是指对 对象的创建.维护.销毁等生命周期的控制,这个过程一般是由我们的程序去主动控制的,如使用new关键字去创建一个 ...
- PCL 编程多个点云合成
博客转载自:https://blog.csdn.net/sunboyiris/article/details/72636809 pcl::PointCloud<pcl::PointXYZRGBA ...