zoukankan      html  css  js  c++  java
  • [luoguP4142]洞穴遇险

    https://www.zybuluo.com/ysner/note/1240792

    题面

    戳我

    解析

    这种用来拼接的奇形怪状的东西,要不就是轮廓线(DP),要不就是网络流。

    为了表示奇数点(即((x+y)\%2=1))的危险值,把该点拆为两个点,连一条边长为该点危险值相反数的边(两点分别称为起点和终点)。

    鉴于一根柱子跨越(3)个格子,其中一点为奇数点,另外两个点都是偶数点,不能区分。

    于是也要把偶数点分为两类(不用拆点)。一类连源点,一类连汇点。连汇点的一类连奇数点的起点,另一类连终点。(让源点出发能到汇点就成)

    然后思考如何表示柱子。

    如果强行给柱子规定方向,则有(8)个方向。
    表示出来,有两种情况,一是(x)轴方向出,(y)轴方向进;另一种是(y)轴方向进,(x)轴方向出。
    于是两个奇数点分别反映一种情况,同时注意相邻的偶数点连奇数点中的起点、还是终点即可。

    还要注意的是,最小费用最大流模板求出的是在最大流前提下的最小流,在后期,可能为了得到最大流而付出更多费用(在本题中就是为了放更多柱子而增加不稳定度)。在费用开始非负时(开始退流时)记得(break)

    唯一一种能让网络流TLE的方式就是cnt=0

    // luogu-judger-enable-o2
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #define re register
    #define il inline
    #define ll long long
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    #define fp(i,a,b) for(re int i=a;i<=b;i++)
    #define fq(i,a,b) for(re int i=a;i>=b;i--)
    using namespace std;
    const int mod=1e9+7,N=5e3+100;
    struct Edge{int to,nxt,w,c;}e[N*10];
    int n,m,k,s,sum,h[N],d[55][55],ans=0,dis[N],S,T,pe[N],pv[N],tot,cnt=1,g;
    bool vis[N],ban[55][55];
    il void add(re int u,re int v,re int w,re int c)
    {
      if(u==-1||v==-1) return ;
      e[++cnt]=(Edge){v,h[u],w,c};h[u]=cnt;
      e[++cnt]=(Edge){u,h[v],0,-c};h[v]=cnt;
    }
    queue<int>Q;
    il ll gi()
    {
       re ll x=0,t=1;
       re char ch=getchar();
       while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
       if(ch=='-') t=-1,ch=getchar();
       while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
       return x*t;
    }
    il int id(re int x,re int y){return (x-1)*n+y;}
    il int SPFA()
    {
      memset(dis,63,sizeof(dis));dis[S]=0;vis[S]=1;Q.push(S);
      while(!Q.empty())
        {
          re int u=Q.front();Q.pop();
          for(re int i=h[u];i+1;i=e[i].nxt)
        {
          re int v=e[i].to;//printf("!!!%d %d
    ",u,v);
          if(dis[v]>dis[u]+e[i].c&&e[i].w)
            {
              dis[v]=dis[u]+e[i].c;
              pe[v]=i;pv[v]=u;
              if(!vis[v]) vis[v]=1,Q.push(v);
            }
        }
          vis[u]=0;
        }
      return dis[T]<dis[0];
    }
    int main()
    {
      //freopen("marshland.in","r",stdin);
      //freopen("marshland.out","w",stdout);
      memset(h,-1,sizeof(h));
      n=gi();m=gi();k=gi();g=n*n;S=2*g+1;T=2*g+2;
      fp(i,1,n)
        fp(j,1,n)
        d[i][j]=gi(),s+=d[i][j];
      fp(i,1,k)
        {
          re int u=gi(),v=gi();
          ban[u][v]=1;
        }
      fp(i,1,n)
        fp(j,1,n)
        {
          if(ban[i][j]) continue;
          if((i+j)%2) add(id(i,j),id(i,j)+g,1,-d[i][j]);
          if((i+j)%2&&j%2==0)
        {
          if(i>1&&!ban[i-1][j]) add(id(i,j)+g,id(i-1,j),1,0);
          if(i<n&&!ban[i+1][j]) add(id(i,j)+g,id(i+1,j),1,0);
          if(j>1&&!ban[i][j-1]) add(id(i,j-1),id(i,j),1,0);
          if(j<n&&!ban[i][j+1]) add(id(i,j+1),id(i,j),1,0);
        }
          if((i+j)%2&&j%2==1)
        {
          if(i>1&&!ban[i-1][j]) add(id(i-1,j),id(i,j),1,0);
          if(i<n&&!ban[i+1][j]) add(id(i+1,j),id(i,j),1,0);
          if(j>1&&!ban[i][j-1]) add(id(i,j)+g,id(i,j-1),1,0);
          if(j<n&&!ban[i][j+1]) add(id(i,j)+g,id(i,j+1),1,0);
        }
          if((i+j)%2==0&&j%2==1) add(S,id(i,j),1,0);
          if((i+j)%2==0&&j%2==0) add(id(i,j),T,1,0);
        }
      while(SPFA()&&m)
        {
          if(dis[T]>=0) break;
          sum=2e9;
          for(re int i=T;i!=S;i=pv[i])
        sum=min(sum,e[pe[i]].w);m-=sum;//printf("%d
    ",sum);
          for(re int i=T;i!=S;i=pv[i])
        e[pe[i]].w-=sum,e[pe[i]^1].w+=sum,ans+=sum*e[pe[i]].c;
        }
      printf("%d
    ",s+ans);
      fclose(stdin);
      fclose(stdout);
      return 0;
    }
    
  • 相关阅读:
    关于sqlserver2008 bcp根据数据表导出xml格式文件的小记
    关于SQL SERVER 2008 X64版本报错:消息 7302,级别 16,无法创建链接服务器 "(null)" 的 OLE DB 访问接口 "Microsoft.ACE.OLEDB.12.0" 的实例。
    Response.Redirect(),Server.Transfer(),Server.Execute()的区别[转]
    ASP.net应用程序中如何调用客户端的Javascript脚本小结(转)
    重写ListView控件,实现点击列头排序的功能
    关于Response.redirect和Response.End出现线程中止异常的处理(转)
    持续集成cruisecontrol.net学习总结
    [转]关于PowerDesigner反向工程SQL Server2000数据库时生成注释的解决方法
    敏捷开发scrum学习笔记一
    asp.net缓存机制总结(转)
  • 原文地址:https://www.cnblogs.com/yanshannan/p/9433035.html
Copyright © 2011-2022 走看看