zoukankan      html  css  js  c++  java
  • LuoguP3356 火星探险问题(费用流)

    题目描述

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

    用一个 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
    ",Ntt,1);
    108             Dfs(ii,jj+1,Ntt);
    109             return ;
    110         }else if(to==z)
    111         {
    112             printf("%d %d
    ",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 }
  • 相关阅读:
    Maximum sum
    走出迷宫
    取石子游戏
    全排列
    BZOJ3456 城市规划
    【SHOI2016】黑暗前的幻想乡
    【AHOI2012】信号塔
    HDU5730 Shell Necklace
    线性常系数齐次递推关系学习笔记
    矩阵树定理学习笔记
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/10210863.html
Copyright © 2011-2022 走看看