• HDU2732 Leapin' Lizards 最大流


    题目

    题意:

    t组输入,然后地图有n行m列,且n,m<=20.有一个最大跳跃距离d。后面输入一个n行的地图,每一个位置有一个值,代表这个位置的柱子可以经过多少个猴子。之后再输入一个地图'L'代表这个位置刚开始有一个猴子.'.'代表这个位置刚开始没有猴子

    题解:

      1 //其实这道题就是建图比较麻烦,其他还是可以的。但是最大的坑点就是
      2 //1、输出的时候的单复数,没有逃出来的猴子数为0、1的时候,要输出lizard和was,否则要输出lizards和were。我也是醉了
      3 //2、他那个条约最大距离是曼哈顿距离——d(i,j)=|X1-X2|+|Y1-Y2|.
      4 
      5 //建图的话。。st是图的起始点,en是图的终止点
      6 //首先要拆点,一个点要拆成两个点i->start和i->last。容量为这个点的承受人数
      7 //如果一个点可以向上、下、左、右移动直接跳出这个图,那他就成功逃生。就让这个i->last和en连一条容量INF的边
      8 //如果一个点它上面原来有猴子(地图上是‘L’),那么就要让起点st和这一个点的i->start相连一条容量为1的边
      9 //如果一个点的曼哈顿距离小于规定距离,就要让i->last和j->start连一条容量INF(无穷大)边.还要建
     10 //j->last和i->start连一条边,因为两个点可以互相往来
     11 //
     12 //同时每建一条正向边,还需要建一条容量为0的反向边
     13 #include<stdio.h>
     14 #include<string.h>
     15 #include<iostream>
     16 #include<algorithm>
     17 #include<queue>
     18 #include<math.h>
     19 #include<stdlib.h>
     20 using namespace std;
     21 const int maxn=100000;
     22 const int INF=0x3f3f3f3f;
     23 int head[maxn],cnt,st,en,dis[maxn],cur[maxn];
     24 struct shudui
     25 {
     26     int x,y,z;
     27 }m[405];
     28 struct edge
     29 {
     30     int v,next,c,flow;
     31 } e[maxn];
     32 void add_edge(int x,int y,int z)
     33 {
     34     e[cnt].v=y;
     35     e[cnt].c=z;
     36     e[cnt].flow=0;
     37     e[cnt].next=head[x];
     38     head[x]=cnt++;
     39 }
     40 bool bfs()
     41 {
     42     memset(dis,0,sizeof(dis));
     43     dis[st]=1;
     44     queue<int>r;
     45     r.push(st);
     46     while(!r.empty())
     47     {
     48         int x=r.front();
     49         r.pop();
     50         for(int i=head[x]; i!=-1; i=e[i].next)
     51         {
     52             int v=e[i].v;
     53             if(!dis[v] && e[i].c>e[i].flow)
     54             {
     55                 dis[v]=dis[x]+1;
     56                 r.push(v);
     57             }
     58         }
     59     }
     60     return dis[en];
     61 }
     62 int dinic(int s,int limit)
     63 {
     64     if(s==en || !limit) return limit;
     65     int ans=0;
     66     for(int &i=cur[s]; i!=-1; i=e[i].next)
     67     {
     68         int v=e[i].v,feed;
     69         if(dis[v]!=dis[s]+1) continue;
     70         feed=dinic(v,min(limit,e[i].c-e[i].flow));
     71         if(feed)
     72         {
     73             e[i].flow+=feed;
     74             e[i^1].flow-=feed;
     75             limit-=feed;
     76             ans+=feed;
     77             if(limit==0) break;
     78         }
     79     }
     80     if(!ans) dis[s]=-1;
     81     return ans;
     82 }
     83 int main()
     84 {
     85 
     86     int t,p=0;
     87     char s[25][25];
     88     int w[25][25];
     89     scanf("%d",&t);
     90     while(t--)
     91     {
     92         int sum=0;
     93         memset(w,0,sizeof(w));
     94         memset(head,-1,sizeof(head));
     95         cnt=0;
     96         int n,d;
     97         scanf("%d%d",&n,&d);
     98         for(int i=1; i<=n; ++i)
     99         {
    100             scanf("%s",s[i]+1);
    101         }
    102         int len=strlen(s[1]+1),number=0;
    103         for(int i=1;i<=n;++i)
    104         {
    105             for(int j=1;j<=len;++j)
    106             {
    107                 if(s[i][j]!='0')
    108                 {
    109                     m[++number].x=i;
    110                     m[number].y=j;
    111                     m[number].z=s[i][j]-'0';
    112                 }
    113             }
    114         }
    115         st=0;
    116         en=2*number+1;
    117         for(int i=1;i<=n;++i)
    118         {
    119             scanf("%s",s[i]+1);
    120         }
    121         for(int i=1;i<=n;++i)
    122         {
    123             for(int j=1;j<=len;++j)
    124             {
    125                 if(s[i][j]=='L')
    126                 {
    127                     sum++;
    128                     w[i][j]=1;
    129                 }
    130             }
    131         }
    132         for(int i=1;i<=number;++i)
    133         {
    134             add_edge(i,i+number,m[i].z);
    135             add_edge(i+number,i,0);
    136             int x=m[i].x;
    137             int y=m[i].y;
    138             if(y<=d || y>len-d || x<=d || x>n-d)
    139             {
    140                 add_edge(i+number,en,INF);
    141                 add_edge(en,i+number,0);
    142             }
    143             if(w[x][y])
    144             {
    145                 add_edge(st,i,1);
    146                 add_edge(i,st,0);
    147             }
    148             for(int j=i+1;j<=number;++j)
    149             {
    150                 int xx=m[j].x;
    151                 int yy=m[j].y;
    152                 int dist=abs(xx-x)+abs(yy-y);
    153                 if(dist<=d)
    154                 {
    155                     add_edge(i+number,j,INF);  //这里还是要建双向边
    156                     add_edge(j,i+number,0);
    157                     add_edge(j+number,i,INF);
    158                     add_edge(i,j+number,0);
    159                 }
    160             }
    161         }
    162 
    163         int ans=0;
    164         while(bfs())
    165         {
    166             for(int i=0; i<=en; i++)
    167                 cur[i]=head[i];
    168             ans+=dinic(st,1);
    169         }
    170 //        if(sum-ans!=0)
    171 //        {
    172 //            if(sum-ans!=1)
    173 //            printf("Case #%d: %d lizards were left behind.
    ",++p,sum-ans);
    174 //            else printf("Case #%d: %d lizard were left behind.
    ",++p,sum-ans);
    175 //        }
    176 //        else printf("Case #%d: no lizard was left behind.
    ",++p);
    177 //我原来这一部分的判断是像注释部分一样,原本我以为我已经绕过了单复数lizard(s),没想到我还是掉坑里了
    178 //后面的were和was也是要改的,我。。。。。。难受
    179         int left=sum-ans;
    180         if(left==0)
    181             printf("Case #%d: no lizard was left behind.
    ",++p);
    182         else if(left==1)
    183             printf("Case #%d: 1 lizard was left behind.
    ",++p);
    184         else printf("Case #%d: %d lizards were left behind.
    ",++p,left);
    185     }
    186     return 0;
    187 }
  • 相关阅读:
    CF627A Xor Equation
    CF865C Gotta Go Fast
    HDU 2222 Keywords Search
    BZOJ 2038: [2009国家集训队]小Z的袜子(hose)
    BZOJ 3781: 小B的询问
    BZOJ 1086: [SCOI2005]王室联邦
    BZOJ 2120: 数颜色
    BZOJ 1503: [NOI2004]郁闷的出纳员
    BZOJ 3757: 苹果树
    BZOJ 1861: [Zjoi2006]Book 书架
  • 原文地址:https://www.cnblogs.com/kongbursi-2292702937/p/11781487.html
Copyright © 2020-2023  润新知