网络流二十四题之二十二 —— 火星探险问题
来源:互联网 发布:rar文件变成网页mac 编辑:程序博客网 时间:2024/06/05 10:12
火星探险问题
Description
火星探险队的登陆舱将在火星表面着陆,登陆舱内有多部障碍物探测车。
登陆舱着陆后,探测车将离开登陆舱向先期到达的传送器方向移动。
探测车在移动中还必须采集岩石标本。
每一块岩石标本由最先遇到它的探测车完成采集。
每块岩石标本只能被采集一次。
岩石标本被采集后,其他探测车可以从原来岩石标本所在处通过。
探测车不能通过有障碍的地面。
本题限定探测车只能从登陆处沿着向南或向东的方向朝传送器移动,而且多个探测车可以在同一时间占据同一位置。
如果某个探测车在到达传送器以前不能继续前进,则该车所采集的岩石标本将全部损失。
用一个PXQ 网格表示登陆舱与传送器之间的位置。登陆舱的位置在(
给定每个位置的状态,计算探测车的最优移动方案,使到达传送器的探测车的数量最多,而且探测车采集到的岩石标本的数量最多。
Input
第
接下来的
用
Output
程序运行结束时,将能探索到的岩石标本数目输出。
Sample Input
2
10
8
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 1 0 0 0
0 0 0 1 0 2 0 0 0 0
1 1 0 1 2 0 0 0 0 1
0 1 0 0 2 0 1 1 0 0
0 1 0 1 0 0 1 1 0 0
0 1 2 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0
Sample Output
2
Solution
我们把每个格子与他能够到达的格子连一条边。
如果此格子有岩石标本,那么就再加一个点,再连一条容量为
跑一遍最大费用流就行了。
Code
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <queue>
- #define ss 0
- #define tt 100000
- #define INF 0x3f3f3f3f
- #define Min(x,y) ((x)<(y)?(x):(y))
- #define PLA(x,y) ((x)*qs+(y))
- #define ANOTHER 1000
- using namespace std;
- int n,cnt,ans,ps,qs;
- int nxt[100010],head[100010],data[100010];
- int flow[100010],wei[100010];
- int dis[100010];
- int pre[100010];
- int maps[100][100];
- bool vis[100][100];
- queue<int>q;
- bool in_stack[100010];
- void add(int x,int y,int a,int b){
- nxt[cnt]=head[x];data[cnt]=y;wei[cnt]=b;flow[cnt]=a;head[x]=cnt++;
- nxt[cnt]=head[y];data[cnt]=x;wei[cnt]=-b;flow[cnt]=0;head[y]=cnt++;
- }
- bool BFS(){
- memset(dis,0x3f,sizeof dis);dis[ss]=0;in_stack[ss]=true;q.push(ss);pre[ss]=pre[tt]=-1;
- while(!q.empty()){
- int now=q.front();
- q.pop();
- in_stack[now]=false;
- for(int i=head[now];i!=-1;i=nxt[i]){
- if(flow[i]!=0&&dis[data[i]]>dis[now]+wei[i]){
- dis[data[i]]=dis[now]+wei[i];
- pre[data[i]]=i^1;
- if(!in_stack[data[i]]){
- in_stack[data[i]]=true;
- q.push(data[i]);
- }
- }
- }
- }
- return pre[tt]!=-1;
- }
- void dfs(){
- int Low=INF;
- for(int i=pre[tt];i!=-1;i=pre[data[i]])Low=Min(Low,flow[i^1]);
- for(int i=pre[tt];i!=-1;i=pre[data[i]])flow[i^1]-=Low,flow[i]+=Low;
- ans+=Low*dis[tt];
- }
- void Dfs(int p1,int p2){
- vis[p1][p2]=true;
- if(p1+1<=ps&&maps[p1+1][p2]!=1){
- if(!maps[p1+1][p2])add(PLA(p1,p2),PLA(p1+1,p2),n,0);
- if(maps[p1+1][p2]==2){
- add(PLA(p1,p2),PLA(p1+1,p2),n,0);
- add(PLA(p1,p2),PLA(p1+1,p2)+ANOTHER,1,0);
- }
- else add(PLA(p1,p2),PLA(p1+1,p2),n,0);
- if(!vis[p1+1][p2])Dfs(p1+1,p2);
- }
- if(p2+1<=qs&&maps[p1][p2+1]!=1){
- if(!maps[p1][p2+1])add(PLA(p1,p2),PLA(p1,p2+1),n,0);
- if(maps[p1][p2+1]==2){
- add(PLA(p1,p2),PLA(p1,p2+1),n,0);
- add(PLA(p1,p2),PLA(p1,p2+1)+ANOTHER,1,0);
- }
- else add(PLA(p1,p2),PLA(p1,p2+1),n,0);
- if(!vis[p1][p2+1])Dfs(p1,p2+1);
- }
- }
- int main(){
- memset(head,-1,sizeof head);
- scanf(”%d%d%d”,&n,&qs,&ps);
- for(int i=1;i<=ps;i++)
- for(int j=1;j<=qs;j++){
- scanf(”%d”,&maps[i][j]);
- add(PLA(i,j)+ANOTHER,PLA(i,j),1,-1);
- }
- Dfs(1,1);
- add(ss,PLA(1,1),n,0);
- add(PLA(ps,qs),tt,n,0);
- while(BFS())dfs();
- if(maps[ps][qs]==2)ans++;
- if(maps[1][1]==2)ans++;
- printf(”%d\n”,-ans);
- return 0;
- }
- 网络流二十四题之二十二 —— 火星探险问题
- 网络流二十四题之十二 —— 软件补丁问题(BUG)
- 【网络流24题】火星探险问题
- 网络流二十四题之二十四 —— 骑士共存问题(KNI)
- 网络流二十四题之十四 —— 孤岛营救问题(RESCUE)
- 网络流二十四题之二 —— 太空飞行计划问题(SHUT)
- 网络流二十四题之二十 —— 深海机器人问题
- 网络流24题23. 火星探险问题
- 网络流二十四题之三 —— 最小路径覆盖问题(PATH)
- 网络流二十四题之四 —— 魔术球问题(BALL)
- 网络流二十四题之五 —— 圆桌问题(TABLE)
- 网络流二十四题之七 —— 试题库问题(DATA)
- 网络流二十四题之九 —— 方格取数问题(GRID)
- 网络流二十四题之十 —— 星际转移问题(HOME)
- 网络流二十四题之十八 —— 分配问题
- 网络流二十四题之十 —— 餐巾计划问题(NAPK)
- 网络流二十四题之十一 —— 航空路线问题(AIRL)
- 网络流二十四题之十六 —— 数字梯形问题(DIGIT)
- php 中FastDFS开启和调用使用
- 蓝牙编程
- HDOJ 1556 Color the ball(树状数组模板)
- Android 9-patch图片制作流程(nine-patch)
- java中unicode和中文相互转换
- 网络流二十四题之二十二 —— 火星探险问题
- App Store2016年最新审核规则
- JQuery动态修改select标签的内容,并绑定onchange事件,弹出选择的值
- Hibernate超简单多表操作
- 深入理解密码技术
- iOS 蓝牙使用小结 bluetooth
- jquery1.11.3源码
- extjs render 用法介绍
- 《程序员面试笔试宝典》学习笔记(四)程序设计基础