zoukankan      html  css  js  c++  java
  • 方格取数(网络流24题)

    题意

    在一个有 m*n 个方格的棋盘中,每个方格中有一个正整数。现要从方格中取数,使任意 2 个数所在方格没有公共边,且取出的数的总和最大。试设计一个满足要求的取数算法。对于给定的方格棋盘,按照取数要求编程找出总和最大的数。

    题解

    方格是常见的二分图(疑问脸)。所以考虑先染色,相邻的格子颜色不同,这样就分成了二分图,先假设全选,然后跑最小割就好了,割掉就是不选。

    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn=10005;
    const int maxm=40005;
    const int inf=1000009;
    int n,m,s,t,ans;
    int cnt=1,head[maxn];
    struct edge{
      int x,y,next,val;
    }e[maxm<<1];
    
    void add(int x,int y,int val){
      e[++cnt]=(edge){x,y,head[x],val};
      head[x]=cnt;
    }
    
    void add_edge(int x,int y,int val){
      add(x,y,val);
      add(y,x,0);
    }
    
    template<class T>inline void read(T &x){
      x=0;char ch=getchar();
      while(!isdigit(ch)) ch=getchar();
      while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    }
    
    int d[maxn];
    
    bool bfs(){
      memset(d,0,sizeof(d));
      queue<int> q;
      q.push(s);d[s]=1;
      while(!q.empty()){
        int x=q.front();
        q.pop();
        for(int i=head[x];i;i=e[i].next){
          int y=e[i].y;
          if(e[i].val&&!d[y]){
            d[y]=d[x]+1;
            if(y==t) return true;
            q.push(y);
          }
        }
      }
      return false;
    }
    
    int dfs(int x,int flow){
      if(x==t) return flow;
      int rest=flow,k;
      for(int i=head[x];i;i=e[i].next){
        int y=e[i].y;
        if(e[i].val&&d[y]==d[x]+1){
          k=dfs(y,min(rest,e[i].val));
          if(!k) d[y]=0;
          e[i].val-=k;
          e[i^1].val+=k;
          rest-=k;
        }
      }
      return flow-rest;
    }
    
    int dinic(){
      int res=0;
      while(bfs()) res+=dfs(s,0x3f3f3f);
      return res;
    }
    
    int main(){
      read(n);read(m);
      s=0;t=n*m+1;
      for(int i=1;i<=n;i++){
        int op=i&1;
        for(int j=1;j<=m;j++){
          int x;read(x);
          ans+=x;
          if(op) {
            add_edge(s,(i-1)*m+j,x);
            if(i>1) add_edge((i-1)*m+j,(i-2)*m+j,inf);
            if(i<n) add_edge((i-1)*m+j,i*m+j,inf);
            if(j>1) add_edge((i-1)*m+j,(i-1)*m+j-1,inf);
            if(j<m) add_edge((i-1)*m+j,(i-1)*m+j+1,inf);
          }
          else add_edge((i-1)*m+j,t,x);
          op^=1;
        }
      }
      ans-=dinic();
      printf("%d",ans);
    }
    View Code

     dfs终止条件没写调了半天(笑哭)

  • 相关阅读:
    python中不可变数据类型和可变数据类型
    你分得清Python中:“索引和切片”吗?
    Python Django中一些少用却很实用的orm查询方法
    jQuery on()方法
    jquery.flexslider-min.js实现banner轮播图效果
    jQuery 树型菜单插件(Treeview)
    jQuery Growl 插件(消息提醒)
    jQuery Autocomplete 用户快速找到并从预设值列表中选择
    jQuery Accordion 插件用于创建折叠菜单
    jquery.validate.js 验证框架详解
  • 原文地址:https://www.cnblogs.com/sto324/p/11336956.html
Copyright © 2011-2022 走看看