zoukankan      html  css  js  c++  java
  • TZOJ 3665 方格取数(2)(最大点权独立集)

    描述

    给你一个m*n的格子的棋盘,每个格子里面有一个非负数。
    从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取数所在的2个格子不能相邻,并且取出的数的和最大。

    输入

    包括多个测试实例,每个测试实例包括2整数m,n和m行n列的非负数(m<=50,n<=50)

    输出

    对于每个测试实例,输出可能取得的最大的和

    样例输入

    3 3
    75 15 21
    75 15 28
    34 70 5

    样例输出

    188

    题意

    如上

    题解

    最大点权独立集=总权值-最小点权覆盖

    用最小割跑出来的是最小点权覆盖,再用sum-最小点权覆盖

    把图黑白染色,黑色点连源点S流量a[i][j],白色点连汇点T流量a[i][j],然后每个相邻的黑白点连黑白边流量INF,跑最小割即可

    代码

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 
      4 const int maxn=1e5+5;
      5 const int maxm=2e5+5;
      6 int n,m,S,T;
      7 int deep[maxn],q[400000];
      8 int FIR[maxn],TO[maxm],CAP[maxm],COST[maxm],NEXT[maxm],tote;
      9 
     10 void add(int u,int v,int cap)
     11 {
     12     TO[tote]=v;
     13     CAP[tote]=cap;
     14     NEXT[tote]=FIR[u];
     15     FIR[u]=tote++;
     16 
     17     TO[tote]=u;
     18     CAP[tote]=0;
     19     NEXT[tote]=FIR[v];
     20     FIR[v]=tote++;
     21 }
     22 bool bfs()
     23 {
     24     memset(deep,0,sizeof deep);
     25     deep[S]=1;q[1]=S;
     26     int head=0,tail=1;
     27     while(head!=tail)
     28     {
     29         int u=q[++head];
     30         for(int v=FIR[u];v!=-1;v=NEXT[v])
     31         {
     32             if(CAP[v]&&!deep[TO[v]])
     33             {
     34                 deep[TO[v]]=deep[u]+1;
     35                 q[++tail]=TO[v];
     36             }
     37         }
     38     }
     39     return deep[T];
     40 }
     41 int dfs(int u,int fl)
     42 {
     43     if(u==T)return fl;
     44     int f=0;
     45     for(int v=FIR[u];v!=-1&&fl;v=NEXT[v])
     46     {
     47         if(CAP[v]&&deep[TO[v]]==deep[u]+1)
     48         {
     49             int Min=dfs(TO[v],min(fl,CAP[v]));
     50             CAP[v]-=Min;CAP[v^1]+=Min;
     51             fl-=Min;f+=Min;
     52         }
     53     }
     54     if(!f)deep[u]=-2;
     55     return f;
     56 }
     57 int maxflow()
     58 {
     59     int ans=0;
     60     while(bfs())
     61         ans+=dfs(S,1<<28);
     62     return ans;
     63 }
     64 void init()
     65 {
     66     tote=0;
     67     memset(FIR,-1,sizeof FIR);
     68 }
     69 int N,M,a[55][55],color[55][55],has[55][55],tot,sum,f;
     70 int main()
     71 {
     72     while(cin>>N>>M)
     73     {
     74         init();
     75         memset(color,0,sizeof color);
     76         tot=sum=0;
     77         for(int i=1;i<=N;i++)
     78         {
     79             if(i&1)f=1;
     80             else f=-1;
     81             for(int j=1;j<=M;f*=-1,j++)
     82             {
     83                 scanf("%d",&a[i][j]);
     84                 sum+=a[i][j];
     85                 has[i][j]=tot++;
     86                 color[i][j]=f;
     87             }
     88         }
     89         S=tot,T=S+1;
     90         for(int i=1;i<=N;i++)
     91             for(int j=1;j<=M;j++)
     92             {
     93                 if(color[i][j]==1)
     94                     add(S,has[i][j],a[i][j]);
     95                 else
     96                     add(has[i][j],T,a[i][j]);
     97                 if(color[i-1][j]==-1)add(has[i][j],has[i-1][j],1<<28);
     98                 if(color[i+1][j]==-1)add(has[i][j],has[i+1][j],1<<28);
     99                 if(color[i][j-1]==-1)add(has[i][j],has[i][j-1],1<<28);
    100                 if(color[i][j+1]==-1)add(has[i][j],has[i][j+1],1<<28);
    101             }
    102         cout<<sum-maxflow()<<'
    ';
    103     }
    104     return 0;
    105 }
  • 相关阅读:
    原生代码实现Promise
    HTTP与HTTPS的区别
    windows常用命令-长期更新
    git 常用命令
    原型和原型链
    vue 中一些API 或属性的常见用法
    移动端屏幕适配
    Nuxt.js(开启SSR渲染)
    vue+element-ui 实现分页(根据el-table内容变换的分页)
    vue中引入jQuery和bootstrap
  • 原文地址:https://www.cnblogs.com/taozi1115402474/p/9535779.html
Copyright © 2011-2022 走看看