P2774 方格取数问题

  1 #include<bits/stdc++.h>
  2 #define _for(i,a,b) for(register int i = (a);i < b;i ++)
  3 #define _rep(i,a,b) for(register int i = (a);i > b;i --)
  4 #define INF 0x3f3f3f3f
  5 #define MOD 100000000
  6 #define maxn 1000003
  7 #define pb push_back
  8 #define debug() printf("Miku Check OK!\n")
  9 typedef long long ll;
 10 
 11 using namespace std;
 12 typedef pair<int,int> P;
 13 inline ll read()
 14 {
 15     ll ans = 0;
 16     char ch = getchar(), last = ' ';
 17     while(!isdigit(ch)) last = ch, ch = getchar();
 18     while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
 19     if(last == '-') ans = -ans;
 20     return ans;
 21 }
 22 inline void write(ll x)
 23 {
 24     if(x < 0) x = -x, putchar('-');
 25     if(x >= 10) write(x / 10);
 26     putchar(x % 10 + '0');
 27 }
 28 int ver[maxn],Next[maxn],head[maxn],val[maxn];
 29 int d[maxn];
 30 int n,m,s,t,tot,maxflow;
 31 const int N = 20000;
 32 void add(int x,int y,int w)
 33 {
 34     ver[++tot] = y,Next[tot] = head[x],head[x] = tot,val[tot] = w;
 35 }
 36 bool bfs()
 37 {
 38     memset(d,0,sizeof(d));
 39     queue<int> q;
 40     q.push(s);
 41     d[s] = 1;
 42     while(!q.empty())
 43     {
 44         int x = q.front();
 45         q.pop();
 46         for(int i = head[x]; i; i = Next[i])
 47             if(val[i] && !d[ver[i]])
 48             {
 49                 q.push(ver[i]);
 50                 d[ver[i]] = d[x]+1;
 51                 if(ver[i]==t)
 52                     return true;
 53             }
 54     }
 55     return false;
 56 }
 57 int dinic(int x,int flow)
 58 {
 59     if(x==t) return flow;
 60     // k为子节点增量
 61     int rest = flow, k;
 62     for(int i = head[x]; i && rest; i = Next[i])
 63     {
 64         if(val[i] && d[ver[i]] == d[x]+1)
 65         {
 66             k = dinic(ver[i],min(rest,val[i]));
 67             if(!k) d[ver[i]] = 0;
 68             val[i] -= k;
 69             val[i^1] += k;
 70             rest -= k;
 71         }
 72     }
 73     return flow - rest;
 74 }
 75 int a[103][103];
 76 int getHash(int x,int y)
 77 {
 78     return x*m+y;
 79 }
 80 int main()
 81 {
 82     n = read();
 83     m = read();
 84     s = 0;
 85     t = 2*N+1;
 86     tot = 1;
 87     maxflow = 0;
 88     int zong = 0;
 89     
 90     _for(i,1,n+1)
 91     _for(j,1,m+1)
 92     {
 93         a[i][j] = read();
 94         zong += a[i][j];
 95         if((i+j)%2)
 96         {
 97             add(s,getHash(i,j),a[i][j]),add(getHash(i,j),s,0);
 98             if(i > 1) {add(getHash(i,j),getHash(i-1,j),INF);add(getHash(i-1,j),getHash(i,j),0);}
 99             if(i < n) {add(getHash(i,j),getHash(i+1,j),INF);add(getHash(i+1,j),getHash(i,j),0);}
100             if(j > 1) {add(getHash(i,j),getHash(i,j-1),INF);add(getHash(i,j-1),getHash(i,j),0);}
101             if(j < m) {add(getHash(i,j),getHash(i,j+1),INF);add(getHash(i,j+1),getHash(i,j),0);}
102         }
103         else
104             {add(getHash(i,j),t,a[i][j]);add(t,getHash(i,j),0);}
105     }
106 
107     int flow = 0;
108     while(bfs())
109         while(flow = dinic(s,INF))
110             maxflow += flow;
111 
112     write(zong-maxflow);
113     return 0;
114 }

 

posted @ 2019-10-09 12:25  Asurudo  阅读(223)  评论(0编辑  收藏  举报