zoukankan      html  css  js  c++  java
  • hdu 2732(网络流)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2732

    思路:如果从某一根柱子能够直接跳到迷宫的外面,那么我们就将这个点连接到汇点。对于哪些不能跳出去但是又有柱子的点,那么 我们就去按照跳跃距离搜寻有没有其他的柱子能够去跳跃,如果能够找到的话,那么连接这两点,并且将容量控制为弧尾节点的柱子数,也正是由于一条弧只能够约 束一个顶点,所以我们需要进行拆点,点内之间流量为本身柱子数。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 #define MAXN 2222
      7 #define MAXM 2222222
      8 #define inf 1<<30
      9 struct Edge{
     10    int v,cap,next;
     11 }edge[MAXM];
     12 int head[MAXN];
     13 int pre[MAXN];
     14 int cur[MAXN];
     15 int level[MAXN];
     16 int gap[MAXN];
     17 int n,m,d,vs,vt,NE,NV;
     18 
     19 void Insert(int u,int v,int cap,int cc=0){
     20    edge[NE].v=v;edge[NE].cap=cap;
     21    edge[NE].next=head[u];head[u]=NE++;
     22 
     23    edge[NE].v=u;edge[NE].cap=cc;
     24    edge[NE].next=head[v];head[v]=NE++;
     25 }
     26 
     27 int sap(int vs,int vt){
     28    memset(pre,-1,sizeof(pre));
     29    memset(level,0,sizeof(level));
     30    memset(gap,0,sizeof(gap));
     31    memcpy(cur,head,sizeof(head));
     32    int u=pre[vs]=vs,aug=inf,maxflow=0;
     33    gap[0]=NV;
     34    while(level[vs]<NV){
     35       loop:
     36       for(int &i=cur[u];i!=-1;i=edge[i].next){
     37          int v=edge[i].v;
     38          if(edge[i].cap&&level[u]==level[v]+1){
     39             aug=min(aug,edge[i].cap);
     40             pre[v]=u;
     41             u=v;
     42             if(v==vt){
     43                maxflow+=aug;
     44                for(u=pre[v];v!=vs;v=u,u=pre[u]){
     45                   edge[cur[u]].cap-=aug;
     46                   edge[cur[u]^1].cap+=aug;
     47                }
     48                aug=inf;
     49             }
     50             goto loop;
     51          }
     52       }
     53       int minlevel=NV;
     54       for(int i=head[u];i!=-1;i=edge[i].next){
     55          int v=edge[i].v;
     56          if(edge[i].cap&&level[v]<minlevel){
     57             minlevel=level[v];
     58             cur[u]=i;
     59          }
     60       }
     61       if(--gap[level[u]]==0)break;
     62       level[u]=minlevel+1;
     63       gap[level[u]]++;
     64       u=pre[u];
     65    }
     66    return maxflow;
     67 }
     68 
     69 char G1[22][22];
     70 char G2[22][22];
     71 int map[22][22];
     72 int mat[22][22];
     73 
     74 int main(){
     75  //  freopen("1.txt","r",stdin);
     76    int _case,t=1,total,sum;
     77    scanf("%d",&_case);
     78    while(_case--){
     79       scanf("%d%d",&n,&d);
     80       memset(map,0,sizeof(map));
     81       memset(mat,0,sizeof(mat));
     82       memset(head,-1,sizeof(head));
     83       for(int i=0;i<n;i++)scanf("%s",G1[i]);
     84       for(int i=0;i<n;i++)scanf("%s",G2[i]);
     85       m=strlen(G1[0]),NE=0,vs=0,total=0,sum=0;
     86       for(int i=0;i<n;i++){
     87          for(int j=0;j<m;j++){
     88             map[i][j]=G1[i][j]-'0';
     89             if(map[i][j]){ mat[i][j]=++total;Insert(2*total-1,2*total,map[i][j]); }
     90          }
     91       }
     92       vt=2*total+1,NV=vt+1;
     93       for(int i=0;i<n;i++){
     94          for(int j=0;j<m;j++){
     95             if(G2[i][j]=='L'){ sum++;Insert(vs,2*mat[i][j]-1,1); }
     96          }
     97       }
     98       for(int i=0;i<n;i++){
     99          for(int j=0;j<m;j++)if(mat[i][j]){
    100             for(int x=-d;x<=d;x++){
    101                for(int y=abs(x)-d;y<=d-abs(x);y++){
    102                   int ii=i+x,jj=j+y;
    103                   if(ii<0||ii>=n||jj<0||jj>=m)continue;
    104                   else if(ii==i&&jj==j)continue;
    105                   else if(mat[ii][jj]==0)continue;
    106                   Insert(2*mat[i][j],2*mat[ii][jj]-1,inf);
    107                }
    108             }
    109             if(i<d||j<d||n-i<=d||m-j<=d)Insert(2*mat[i][j],vt,inf);
    110          }
    111       }
    112       int ans=sum-sap(vs,vt);
    113       printf("Case #%d: ",t++);
    114       if(ans==0){
    115          printf("no lizard was left behind.\n");
    116       }else if(ans==1){
    117          printf("1 lizard was left behind.\n");
    118       }else {
    119          printf("%d lizards were left behind.\n",ans);
    120       }
    121    }
    122    return 0;
    123 }
    View Code
  • 相关阅读:
    Rstudio代码的快捷键
    sqlhelper帮助类
    图片上传
    反射获取 obj类 的属性 与对应值
    jquery 操作 动态创建的 元素
    Path类使用
    jquery 小数计算保持精度
    js字符串转成数字
    DateTime.Now.ToString()的各种字符串
    Linq语句 动态组建
  • 原文地址:https://www.cnblogs.com/wally/p/3117398.html
Copyright © 2011-2022 走看看