题目描述

火星探险队的登陆舱将在火星表面着陆,登陆舱内有多部障碍物探测车。登陆舱着陆后,探测车将离开登陆舱向先期到达的传送器方向移动。探测车在移动中还必须采集岩石标本。每一块岩石标本由最先遇到它的探测车完成采集。每块岩石标本只能被采集一次。岩石标本被采集后,其他探测车可以从原来岩石标本所在处通过。探测车不能通过有障碍的地面。本题限定探测车只能从登陆处沿着向南或向东的方向朝传送器移动,而且多个探测车可以在同一时间占据同一位置。如果某个探测车在到达传送器以前不能继续前进,则该车所采集的岩石标本将全部损失。

用一个 P·Q 网格表示登陆舱与传送器之间的位置。登陆舱的位置在(X1,Y1)处,传送器

的位置在(XP ,YQ)处。

X 1,Y 1 X 2 , Y 1 X 3 , Y 1 ... X P-1, Y 1 X P , Y 1

X 1,Y 2 X 2 , Y 2 X 3 , Y 2 ... X P-1, Y 2 X P , Y 2

X 1, Y 3 X 2 , Y 3 X 3 ,Y 3 ... X P-1, Y 3 X P , Y 3

... ...

X 1 ,Y Q-1 X 2 , Y Q-1 X 3 , Y Q-1 ... X P-1, Y Q-1 X P , Y Q-1

X 1,Y Q X 2 , Y Q X 3 , Y Q ... X P-1, Y Q X P ,Y Q

给定每个位置的状态,计算探测车的最优移动方案,使到达传送器的探测车的数量最多,

而且探测车采集到的岩石标本的数量最多

输入输出格式

输入格式:

第 1行为探测车数,第 2 行为 P 的值,第3 行为Q 的值。接下来的 Q 行是表示登陆舱与传送器之间的位置状态的 P·Q 网格。用 3 个数字表示火星表面位置的状态:0 表示平坦无障碍,1表示障碍,2 表示石块。

输出格式:

每行包含探测车号和一个移动方向,0 表示向南移动,1 表示向东移动。

解题思路:

拆点套路。

代码:

  1 #include<queue>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 typedef long long lnt;
  6 const int oo=0x3f3f3f3f;
  7 struct pnt{
  8     int hd;
  9     int lst;
 10     int pre;
 11     int dis;
 12     int val;
 13     bool vis;
 14 }p[100000];
 15 struct ent{
 16     int twd;
 17     int lst;
 18     int vls;
 19     int dis;
 20     int his;
 21 }e[100000];
 22 struct int_2{
 23     int i,j;
 24 }pi[100000];
 25 int cnt;
 26 int n,m;
 27 int s,t;
 28 int num;
 29 int mp[101][101];
 30 int no[101][101][2];
 31 std::queue<int>Q;
 32 void ade(int f,int t,int v,int d)
 33 {
 34     cnt++;
 35     e[cnt].his=v;
 36     e[cnt].twd=t;
 37     e[cnt].vls=v;
 38     e[cnt].dis=d;
 39     e[cnt].lst=p[f].hd;
 40     p[f].hd=cnt;
 41     return ;
 42 }
 43 bool Spfa(void)
 44 {
 45     while(!Q.empty())
 46         Q.pop();
 47     for(int i=1;i<=t;i++)
 48     {
 49         p[i].dis=p[i].val=oo;
 50         p[i].vis=false;
 51     }
 52     p[t].pre=-1;
 53     p[s].vis=true;
 54     p[s].dis=0;
 55     Q.push(s);
 56     while(!Q.empty())
 57     {
 58         int x=Q.front();
 59         Q.pop();
 60         p[x].vis=false;
 61         for(int i=p[x].hd;i;i=e[i].lst)
 62         {
 63             int to=e[i].twd;
 64             if(p[to].dis>p[x].dis+e[i].dis&&e[i].vls>0)
 65             {
 66                 p[to].dis=p[x].dis+e[i].dis;
 67                 p[to].val=std::min(p[x].val,e[i].vls);
 68                 p[to].pre=x;
 69                 p[to].lst=i;
 70                 if(p[to].vis)
 71                     continue;
 72                 p[to].vis=true;
 73                 Q.push(to);
 74             }
 75         }
 76     }
 77     return p[t].pre!=-1;
 78 }
 79 int Ek(void)
 80 {
 81     int ans=0;
 82     while(Spfa())
 83     {
 84         ans+=p[t].val;
 85         for(int i=t;i!=s;i=p[i].pre)
 86         {
 87             e[p[i].lst].vls-=p[t].val;
 88             e[((p[i].lst-1)^1)+1].vls+=p[t].val;
 89         }
 90     }
 91     return ans;
 92 }
 93 void Dfs(int ii,int jj,int Ntt)
 94 {
 95     int w=no[ii][jj][1];
 96     int x=no[ii][jj][0];
 97     int y=no[ii][jj+1][0];
 98     int z=no[ii+1][jj][0];
 99     for(int i=p[w].hd;i;i=e[i].lst)
100     {
101         if(e[i].vls>=e[i].his)
102             continue;
103         e[i].vls++;
104         int to=e[i].twd;
105         if(to==y)
106         {
107             printf("%d %d\n",Ntt,1);
108             Dfs(ii,jj+1,Ntt);
109             return ;
110         }else if(to==z)
111         {
112             printf("%d %d\n",Ntt,0);
113             Dfs(ii+1,jj,Ntt);
114             return ;
115         }
116     }
117     return ;
118 }
119 int main()
120 {
121 //    freopen("a.in","r",stdin);
122     scanf("%d%d%d",&num,&m,&n);
123     for(int i=1;i<=n;i++)
124     {
125         for(int j=1;j<=m;j++)
126         {
127             no[i][j][0]=++cnt;
128             pi[cnt]=(int_2){i,j};
129         }
130     }
131     for(int i=1;i<=n;i++)
132     {
133         for(int j=1;j<=m;j++)
134         {
135             no[i][j][1]=++cnt;
136             pi[cnt]=(int_2){i,j};
137         }
138     }
139     s=cnt+1;
140     t=cnt+2;
141     cnt=0;
142     for(int i=1;i<=n;i++)
143     {
144         for(int j=1;j<=m;j++)
145         {
146             scanf("%d",&mp[i][j]);
147             if(mp[i][j]==1)
148                 continue;
149             if(mp[i][j]==2)
150             {
151                 ade(no[i][j][0],no[i][j][1],1,-1);
152                 ade(no[i][j][1],no[i][j][0],0,1);
153             }
154             ade(no[i][j][0],no[i][j][1],oo,0);
155             ade(no[i][j][1],no[i][j][0],0,0);
156         }
157     }
158
159     for(int i=1;i<=n;i++)
160     {
161         for(int j=1;j<=m;j++)
162         {
163             if(mp[i][j]==1)
164                 continue;
165             if(i+1<=n&&mp[i+1][j]!=1)
166             {
167                 ade(no[i][j][1],no[i+1][j][0],oo,0);
168                 ade(no[i+1][j][0],no[i][j][1],0,0);
169             }
170             if(j+1<=m&&mp[i][j+1]!=1)
171             {
172                 ade(no[i][j][1],no[i][j+1][0],oo,0);
173                 ade(no[i][j+1][0],no[i][j][1],0,0);
174             }
175         }
176     }
177     ade(s,no[1][1][0],num,0);
178     ade(no[1][1][0],s,0,0);
179     ade(no[n][m][1],t,num,0);
180     ade(t,no[n][m][1],0,0);
181     num=Ek();
182     for(int i=1;i<=num;i++)
183         Dfs(1,1,i);
184     return 0;
185 }

转载于:https://www.cnblogs.com/blog-Dr-J/p/10210863.html

LuoguP3356 火星探险问题(费用流)相关推荐

  1. 洛谷 - P3356 火星探险问题(最大费用最大流+拆点+路径打印)

    题目链接:点击查看 题目大意:给出一个n*m的矩阵,每个点都有一个数字: 0:平坦无障碍 1:障碍 2:石块 现在在点(1,1)处有k个探测车,他们都要去往点(n,m)处,探测车只能向下或向右行驶,现 ...

  2. [P1149] TSOI南湖探险(费用流)

    背景 NOIP2009,TSOI大爆发,创造了历史,书写了传奇.于是,在SRC的提议下,大家一起去南湖公园探险. 描述 南湖地区的地形错综复杂.这里有茂密的原始森林,有一望无际的湖水,有大自然一切钟灵 ...

  3. P3356 火星探险问题(网络流)

    P3356 火星探险问题 对于一个第一次经过会有价值,但是之后经过没有价值的点,我们的处理方法就是只连一条流量为1并且有费用的边,再连接流量为INF但是没有费用的边,这样我们要使得价值最大就会优先流有 ...

  4. 网络流二十四题之二十二 —— 火星探险问题

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

  5. BZOJ3291Alice与能源计划——匈牙利算法+模拟费用流

    题目描述 在梦境中,Alice来到了火星.不知为何,转眼间Alice被任命为火星能源部长,并立刻面临着一个严峻的考验.为 了方便,我们可以将火星抽象成平面,并建立平面直角坐标系.火星上一共有N个居民点 ...

  6. [哈希][费用流]JZOJ 3296 【SDOI2013】刺客信条

    Description 故事发生在1486 年的意大利,Ezio 原本只是一个文艺复兴时期的贵族,后来因为家族成员受到圣殿骑士的杀害,决心成为一名刺客.最终,凭借着他的努力和出众的天赋,成为了杰出的刺 ...

  7. [BZOJ 1221][HNOI2001]软件开发(费用流)

    Description 某软件公司正在规划一项n天的软件开发计划,根据开发计划第i天需要ni个软件开发人员,为了提高软件开发人员的效率,公司给软件人员提供了很多的服务,其中一项服务就是要为每个开发人员 ...

  8. 费用流 -- 四川省赛F-Direction Setting [拆边成点+费用流]

    题目链接 题目大意: 就是给你一个nnn个点mmm条边的无向图,每个点有个值是aia_iai​现在你把每条边都赋予一个方向之后这个图就是有向图了,那么设第iii个点的入度是did_idi​,现在设 D ...

  9. UVA1411 Ants(带权二分图的最大完美匹配、zkw费用流)

    题解 给定一些黑点白点,要求一个黑点链接一个白点并且线段不相交(转成二分图最大权匹配使用费用流解决)<训练指南>P351 输出方案:满流即为答案(满流是指这条路的流量跑满了,也就是说edg ...

  10. 餐巾计划问题 线性规划与网络流24题之10 费用流

    相关知识:最小费用(最大)流 问题描述: 一个餐厅在相继的N 天里, 每天需用的餐巾数不尽相同. 假设第i天需要ri块餐巾(i=1, 2,-,N).餐厅可以购买新的餐巾,每块餐巾的费用为p分:或者把旧 ...

最新文章

  1. Excel导入SQL数据库完整代码
  2. 电脑族必备的6款神器,第1个都让人惊艳了!
  3. ES6 for...of循环
  4. 记得5年前左右的时候,IT这块刚好处于最火专业之一!至今为止,依旧很多人选择计算机!由于女生也很多选择这块,所以给很多公司带来了福利啊!以前一个互联网公司女生少的可怜啊!可随着IT这块人员的进入,竞争
  5. ubuntu终端下快捷键,字体放大缩小等【逐渐完善篇】
  6. html标签object和embed,html标签object和embed的区别
  7. java项目所需jar包的下载--maven仓库
  8. 扎根CNCF社区贡献五年是怎样的体验?听听华为云原生开源团队的负责人怎么说
  9. 牛客小白月赛13 解题报告
  10. Linux上安装Oracle 10g 装后感
  11. android定位坑简书,android webview 定位问题
  12. SpringBoot整合tkMybatis基础教程
  13. 在OPENSTACK中 WIN7和WIN2008 R2实例启动时蓝屏报 STOP:0X0000005DT
  14. dell云存储服务器,dell云存储服务器(戴尔存储服务器)
  15. android:layout_weight=1,Android中的Layout_weight(权重)详解
  16. vs2008设置选中 高亮
  17. 从Technorati看博客搜索的发展
  18. NYOJ:33-蛇形填数
  19. win10打开蓝牙,蓝牙开关消失,蓝牙和其他设备设置,蓝牙开关不见了
  20. Bootstrap03

热门文章

  1. 怎样才能叫高级程序员?
  2. java 假币问题_减治法解决假币问题
  3. 微信开发者工具模拟扫描二维码调试
  4. NLP(四十二)人物关系分类的再次尝试
  5. JavaScript中的函数 1
  6. 一款自制的视频录制软件
  7. P3369普通平衡树
  8. linux安全-用户行为监控
  9. grafana-普罗米修斯-监控linux-windows版
  10. 宝宝专业智力测试软件,儿童医院心理科做智商检测-儿童智力测试仪_儿童注意力测试仪_儿童综合素质测试仪/测评系统...