zoukankan      html  css  js  c++  java
  • hdu1565方格取数(1)【最大流||最大点权独立集】

    Problem Description
    给你一个n*n的格子的棋盘,每个格子里面有一个非负数。
    从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大。
     
    Input
    包括多个测试实例,每个测试实例包括一个整数n 和n*n个非负数(n<=20)
     
    Output
    对于每个测试实例,输出可能取得的最大的和
     
    Sample Input
    3 75 15 21 75 15 28 34 70 5
     
    Sample Output
    188
     
    预备知识:
    对于一个无向图G,点有各自的权值
     
    点覆盖集:一个点集,使G中所有的边至少有一个点在该集合内
    最小点权覆盖集:权值和最小的点覆盖集
     
    点独立集:一个点集,该集合中任意两个点都没有边相连
    最大点权独立集:全职和最大的点独立集
     
    定理:
    1、最小点权覆盖集 = 最小割 = 最大流
    2、最大点权独立集 = 总权值 - 最小点权覆盖集
     
    分析:
    该题是二分图中的最大点权独立集的题目
    可以用网络流来做
    将每个格子抽象成一个点,相邻格子分别涂成黑色和白色
    将源点和白色点连一条边,权值为白色点的权值
    将白点和它所能到达的白点连一条边,权值为INF
    将黑点和汇点连一条边,权值为黑点的权值
    这样求出来的网络流便是最小点权覆盖集
    然后用总权值减去即可
    细节处理:将图上的各点先转化为数字,奇数行奇数列上的点跟偶数行偶数列上的点是同色的
     
    代码:
      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <vector>
      5 #include <queue>
      6 using namespace std;
      7 
      8 const int maxn = 205 << 1;
      9 const int INF = 1000000000;
     10 
     11 int map[25][25], a[25][25];
     12 int xx[4] = { 0, 0, 1, -1 };
     13 int yy[4] = { 1, -1, 0, 0 };
     14 
     15 struct Edge
     16 {
     17     int from, to, cap, flow;
     18 };
     19 
     20 struct Dinic
     21 {
     22     int n, m, s, t;
     23     vector<Edge> edges;
     24     vector<int>G[maxn];
     25     bool vis[maxn];
     26     int d[maxn];
     27     int cur[maxn];
     28 
     29     void ClearAll(int n) {
     30         for(int i = 0; i <= n; i++) {
     31             G[i].clear();
     32         }
     33         edges.clear();
     34     }
     35 
     36     void AddEdge(int from, int to, int cap) {
     37         edges.push_back((Edge){from, to, cap, 0} );
     38         edges.push_back((Edge){to, from, 0, 0} );
     39         m = edges.size();
     40         G[from].push_back(m - 2);
     41         G[to].push_back(m - 1);
     42         //printf("%din end
    ",m);
     43     }
     44 
     45     bool BFS()
     46     {
     47         memset(vis, 0, sizeof(vis) );
     48         queue<int> Q;
     49         Q.push(s);
     50         vis[s] = 1;
     51         d[s] = 0;
     52         while(!Q.empty() ){
     53             int x = Q.front(); Q.pop();
     54             for(int i = 0; i < G[x].size(); i++) {
     55                 Edge& e = edges[G[x][i]];
     56                 if(!vis[e.to] && e.cap > e.flow) {
     57                     vis[e.to] = 1;
     58                     d[e.to] = d[x] + 1;
     59                     Q.push(e.to);
     60                 }
     61             }
     62         }
     63         return vis[t];
     64     }
     65 
     66     int DFS(int x, int a) {
     67         if(x == t || a == 0) return a;
     68         int flow = 0, f;
     69         for(int& i = cur[x]; i < G[x].size(); i++) {
     70             Edge& e = edges[G[x][i]];
     71             if(d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap - e.flow))) > 0) {
     72                 e.flow += f;
     73                 edges[G[x][i]^1].flow -= f;
     74                 flow += f;
     75                 a -= f;
     76                 if(a == 0) break;
     77             }
     78         }
     79         return flow;
     80     }
     81 
     82     int MaxFlow(int s, int t) {
     83         this -> s = s; this -> t = t;
     84         int flow = 0;
     85         while(BFS()) {
     86             memset(cur, 0, sizeof(cur));
     87             flow += DFS(s, INF);
     88         }
     89         return flow;
     90     }
     91 };
     92 
     93 Dinic g;
     94 
     95 int main() {
     96     int n;
     97     //freopen("b.txt","r",stdin);
     98     while(EOF != scanf("%d",&n) ) {
     99         int tot = 1;
    100         int sum = 0;
    101         int s = 0; int t = n * n + 1;
    102         for(int i = 1;i <= n; i++) {
    103             for(int j = 1; j <= n; j++) {
    104                 scanf("%d",&a[i][j]);
    105                 sum += a[i][j];
    106                 map[i][j] = tot++;
    107             }
    108         }
    109         g.ClearAll(maxn);
    110         for(int i = 1; i <= n; i++) {
    111             for(int j = 1; j <= n; j++) {
    112 
    113                 if(i % 2 == 1 && j % 2 == 1) {
    114                     g.AddEdge(s, map[i][j], a[i][j]);
    115                     for(int k = 0; k < 4; k++) {
    116                         int tmpx = i + xx[k]; int tmpy = j + yy[k];
    117                         if(tmpx >= 1 && tmpx <= n && tmpy >= 1 && tmpy <= n) {
    118                             g.AddEdge(map[i][j], map[tmpx][tmpy], INF);
    119                             //printf("%d %d %d
    ",tmpx, tmpy, map[tmpx][tmpy]);
    120                         }
    121                     }
    122                 }
    123 
    124                 if(i % 2 == 0 && j % 2 == 0) {
    125                     g.AddEdge(s, map[i][j], a[i][j]);
    126                     for(int k = 0; k < 4; k++) {
    127                         int tmpx = i + xx[k]; int tmpy = j + yy[k];
    128                         if(tmpx >= 1 && tmpx <= n && tmpy >= 1 && tmpy <= n) {
    129                             g.AddEdge(map[i][j], map[tmpx][tmpy], INF);
    130                         }
    131                     }
    132                 }
    133 
    134                 if(i % 2 == 1 && j % 2 == 0) {
    135                     g.AddEdge(map[i][j], t, a[i][j]);
    136                 }
    137                 if(i % 2 == 0 && j % 2 == 1) {
    138                     g.AddEdge(map[i][j], t, a[i][j]);
    139                 }
    140             }
    141         }
    142         //printf("%d %d
    ",sum, g.MaxFlow(s, t));
    143         printf("%d
    ",sum - g.MaxFlow(s, t) );
    144     }
    145     return 0;
    146 }
    View Code
  • 相关阅读:
    通过静态广播监听网络变化,在通过回调通知
    支付宝九宫格
    toolBar
    QQ发送位置(高德地图)
    聊天消息 左右item
    Scrollview 嵌套 RecyclerView 及在Android 5.1版本滑动时 惯性消失问题
    判断软键盘是否弹出 并且隐藏
    Solve Longest Path Problem in linear time
    Why longest path problem doesn't have optimal substructure?
    [leetcode] Reorder List
  • 原文地址:https://www.cnblogs.com/zhanzhao/p/3754873.html
Copyright © 2011-2022 走看看