zoukankan      html  css  js  c++  java
  • bzoj1066: [SCOI2007]蜥蜴(最大流)

    1066: [SCOI2007]蜥蜴

    题目:传送门 


    题解:

       哇QTT大佬一眼秒算法...ORT

       其实很容易就可以看出来是一道最大流

       因为有边的使用限制,那么就可以直接当成是流量来处理嘛

       因为是对点进行操作,那么就可以拆点啊

       一开始现将有柱子的点自己把限制条件连上,就是对点x拆成x1和x2那么就x1-->x2流量为限制

       然后就是无脑乱连,对于判断是否出了边界一开始还傻逼逼的没想出来。。。

       枚举多一圈界外的点,那么如果算曼哈顿距离(据说欧几里得也OK)符合条件,就判断是不是在界内:

       在界内就直接连嘛,对于点x和点y,x2-->y1流量无限

       在界外那就很nice,直接向ed连无限流量。

       最后就是对于每个蜥蜴的操作了,直接st连蜥蜴流量为1(因为柱子上只可能有一只)

        


    代码:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cstdlib>
     4 #include<cmath>
     5 #include<algorithm>
     6 #define inf 999999999
     7 using namespace std;
     8 struct node
     9 {
    10     int x,y,c,next,other;
    11 }a[1110000];int len,last[11000];
    12 void ins(int x,int y,int c)
    13 {
    14     int k1,k2;
    15     k1=++len;
    16     a[len].x=x;a[len].y=y;a[len].c=c;
    17     a[len].next=last[x];last[x]=len;
    18     
    19     k2=++len;
    20     a[len].x=y;a[len].y=x;a[len].c=0;
    21     a[len].next=last[y];last[y]=len;
    22     
    23     a[k1].other=k2;
    24     a[k2].other=k1;
    25 }
    26 int n,m,D,head,tail,st,ed;
    27 int list[11000],h[111000];
    28 bool bt_h()
    29 {
    30     memset(h,0,sizeof(h));h[st]=1;
    31     list[1]=st;head=1;tail=2;
    32     while(head!=tail)
    33     {
    34         int x=list[head];
    35         for(int k=last[x];k;k=a[k].next)
    36         {
    37             int y=a[k].y;
    38             if(h[y]==0 && a[k].c>0)
    39             {
    40                 h[y]=h[x]+1;
    41                 list[tail++]=y;
    42             }
    43         }
    44         head++;
    45     }
    46     if(h[ed]>0)return true;
    47     return false;
    48 }
    49 int find_flow(int x,int flow)
    50 {
    51     if(x==ed)return flow;
    52     int s=0,t;
    53     for(int k=last[x];k;k=a[k].next)
    54     {
    55         int y=a[k].y;
    56         if(h[y]==h[x]+1 && a[k].c>0 && s<flow)
    57         {
    58             s+=t=find_flow(y,min(a[k].c,flow-s));
    59             a[k].c-=t;a[a[k].other].c+=t;
    60         }
    61     }
    62     if(s==0)h[x]=0;
    63     return s;
    64 }
    65 char A[66][66],B[66][66];
    66 int d[66][66];
    67 int main()
    68 {
    69     scanf("%d%d%d",&n,&m,&D);int ss=0;
    70     for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)d[i][j]=++ss;
    71     for(int i=1;i<=n;i++)scanf("%s",A[i]+1);
    72     for(int i=1;i<=n;i++)scanf("%s",B[i]+1);
    73     len=0;memset(last,0,sizeof(last));
    74     st=2*n*m+1,ed=st+1;
    75     for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)if(A[i][j]!='0')ins(d[i][j],d[i][j]+n*m,A[i][j]-'0');
    76     for(int i=1;i<=n;i++)
    77         for(int j=1;j<=m;j++)
    78             if(A[i][j]!='0')
    79                 for(int tx=0;tx<=n+1;tx++)
    80                     for(int ty=0;ty<=m+1;ty++)
    81                         if(abs(i-tx)+abs(j-ty)<=D)
    82                             if(tx>=1 && tx<=n && ty>=1 && ty<=m)ins(d[i][j]+n*m,d[tx][ty],inf);
    83                             else ins(d[i][j]+n*m,ed,inf);
    84     int sum=0;
    85     for(int i=1;i<=n;i++)
    86         for(int j=1;j<=m;j++)
    87             if(B[i][j]=='L')
    88                 ins(st,d[i][j],1),sum++;
    89     int ans=0;
    90     while(bt_h())ans+=find_flow(st,inf);
    91     printf("%d
    ",sum-ans);
    92     return 0;
    93 }
  • 相关阅读:
    nacos安装配置和部署教程
    springcloudstream整合rabbitmq
    Springboot整合swagger2
    git命令详解
    Mybatis 注解开发传入List 两种方式接收方式 在IN场景中
    java 根据时间段查询数据库
    stream分页
    201521123068《Java程序设计》第1周学习总结
    201521123027 《JAVA程序设计》第二周学习总结
    201521123027 《JAVA程序设计》第一周学习总结
  • 原文地址:https://www.cnblogs.com/CHerish_OI/p/8653645.html
Copyright © 2011-2022 走看看