zoukankan      html  css  js  c++  java
  • 方格取数 【网络流24题】【最小割】

    输入输出样例

    输入 #1
    3 3
    1 2 3
    3 2 3
    2 3 1 
    输出 #1
    11

    思路

      因为要保证一个点不能和他有共同边的点接触

      很容易想到把所有点划分为两个阵营

      显然一个横纵坐标相加为偶数的点

      其所接触的点横纵坐标相加为奇数

      于是得到二分图划分的依据:横纵坐标相加和的奇偶性

      把偶数阵营连边S,奇数阵营连边T

      奇偶阵营之间连边 INF

      就是本踢的二分图模型

      通过观察可以发现,图中向S、T连边象征了一种抉择

      当两个有公共边的点可以流通时,显然是不满足要求的

      考虑删除这种边且使得花费最小

      发现这是个最小割问题

      通过在相邻点之间连流量为 inf 的边可以保证割去的一定是某个点连向 S 或 T 的边

      这个时候答案就等于所有点的总权值和 - 最小割 = SUM  - MAXFLOW

    CODE

      1 #include <bits/stdc++.h>
      2 #define dbg(x) cout << #x << "=" << x << endl
      3 #define eps 1e-8
      4 #define pi acos(-1.0)
      5 
      6 using namespace std;
      7 typedef long long LL;
      8 
      9 const LL inf = 0x7f7f7f7f;
     10 
     11 template<class T>inline void read(T &res)
     12 {
     13     char c;T flag=1;
     14     while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
     15     while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
     16 }
     17 
     18 namespace _buff {
     19     const size_t BUFF = 1 << 19;
     20     char ibuf[BUFF], *ib = ibuf, *ie = ibuf;
     21     char getc() {
     22         if (ib == ie) {
     23             ib = ibuf;
     24             ie = ibuf + fread(ibuf, 1, BUFF, stdin);
     25         }
     26         return ib == ie ? -1 : *ib++;
     27     }
     28 }
     29 
     30 int qread() {
     31     using namespace _buff;
     32     int ret = 0;
     33     bool pos = true;
     34     char c = getc();
     35     for (; (c < '0' || c > '9') && c != '-'; c = getc()) {
     36         assert(~c);
     37     }
     38     if (c == '-') {
     39         pos = false;
     40         c = getc();
     41     }
     42     for (; c >= '0' && c <= '9'; c = getc()) {
     43         ret = (ret << 3) + (ret << 1) + (c ^ 48);
     44     }
     45     return pos ? ret : -ret;
     46 }
     47 
     48 const int maxn = 200007;
     49 
     50 int n, m;
     51 int s, t;
     52 
     53 struct edge{
     54     int from,to;
     55     LL cap,flow;
     56 };
     57 
     58 struct DINIC {
     59     int head[maxn << 1], nxt[maxn << 1], edge[maxn << 1], cnt;
     60     int cap[maxn << 1], depth[maxn << 1];
     61 
     62     void init() {
     63         cnt = 1;
     64         memset(head, 0, sizeof(head));
     65     }
     66 
     67     void BuildGraph(int u, int v, int w) {
     68         ++cnt;
     69         edge[cnt] = v;
     70         nxt[cnt] = head[u];
     71         cap[cnt] = w;
     72         head[u] = cnt;
     73 
     74         ++cnt;
     75         edge[cnt] = u;
     76         nxt[cnt] = head[v];
     77         cap[cnt] = 0;
     78         head[v] = cnt;
     79     }
     80 
     81     queue<int> q;
     82 
     83     bool bfs() {
     84         memset(depth, 0, sizeof(depth));
     85         depth[s] = 1;
     86         q.push(s);
     87         while(!q.empty()) {
     88             int u = q.front();
     89             q.pop();
     90             for ( int i = head[u]; i; i = nxt[i] ) {
     91                 int v = edge[i];
     92                 if(depth[v]) {
     93                     continue;
     94                 }
     95                 if(cap[i]) {
     96                     depth[v] = depth[u] + 1;
     97                     q.push(v);
     98                 }
     99             }
    100         }
    101         //printf("dep[%d]:%d
    ",t, depth[t]);
    102         return depth[t];
    103     }
    104 
    105     int dfs(int u, int dist) {
    106         if(u == t) {
    107             return dist;
    108         }
    109         int flow = 0;
    110         for ( int i = head[u]; i && dist; i = nxt[i] ) {
    111             if(cap[i] == 0)
    112                 continue;
    113             int v = edge[i];
    114             if(depth[v] != depth[u] + 1) {
    115                 continue;
    116             }
    117             int res = dfs(v, min(cap[i], dist));
    118             cap[i] -= res;
    119             cap[i ^ 1] += res;
    120             //printf("cap[%d]:%d
    ",t, cap[t]);
    121             dist -= res;
    122             flow += res;
    123         }
    124         return flow;
    125     }
    126 
    127     int maxflow() {
    128         int ans = 0;
    129         while(bfs()) {
    130             ans += dfs(s, inf);
    131         }
    132         return ans;
    133     }
    134 } dinic;
    135 
    136 int dr[4] = {1, 0, -1, 0};
    137 int dc[4] = {0, 1, 0, -1};
    138 
    139 inline int id(int a, int b) {
    140     return (a - 1) * n + b;
    141 }
    142 
    143 int main()
    144 {
    145     //freopen("data.txt", "r", stdin);
    146     read(m); read(n);
    147     int sum = 0;
    148     s = 0, t = n * m + 1;
    149     dinic.init();
    150     for ( int i = 1; i <= m; ++i ) {
    151         for ( int j = 1; j <= n; ++j ) {
    152             int x;
    153             read(x);
    154             sum += x;
    155             if(((i + j) & 1) == 0) {
    156                 dinic.BuildGraph(s, id(i, j), x);
    157                 for ( int k = 0; k < 4; ++k ) {
    158                     int xx = i + dr[k], yy = j + dc[k];
    159                     if(xx <= m && xx >= 1 && yy <= n && yy >= 1) {
    160                         dinic.BuildGraph(id(i, j), id(xx, yy), inf);
    161                     }
    162                     
    163                 }
    164             }
    165             else {
    166                 dinic.BuildGraph(id(i, j), t, x);
    167             }
    168         }
    169     }
    170     int res = dinic.maxflow();
    171     //dbg(res);
    172     cout << sum - res << endl;
    173     return 0;
    174 }
    View Code
  • 相关阅读:
    ExtAspNet下通过文档路径实现文档的下载
    ExtjS学习--------Ext.define定义类
    【C语言天天练(二三)】errno变量
    Linux 内核kobject 层次, kset, 和子系统
    Linux 内核释放函数和 kobject 类型
    Linux 内核引用计数的操作
    Linux 内核 kobject 初始化
    Linux 内核 嵌入的 kobjects
    Kobjects, Ksets 和 Subsystems
    Kobjects, Ksets 和 Subsystems
  • 原文地址:https://www.cnblogs.com/orangeko/p/12670800.html
Copyright © 2011-2022 走看看