码迷,mamicode.com
首页 > 其他好文 > 详细

hdu_1565(网络流)

时间:2015-03-06 00:54:39      阅读:208      评论:0      收藏:0      [点我收藏+]

标签:

解法一、网络流

相邻的点染不同颜色:

  (行数+列数)为奇数的染成白色,(行数+列数)为偶数的染成白色

source = 0, sink = n*n+1.

source到每个白点连接,流量为白点的值

黑点到sink连接,流量为黑点的值

每个白点与其周围的黑点连接,流量为INT_MAX

所有点的值的总和 - 最大流量 = 所求答案

 

以下是抄来的原理:

  点覆盖集:无向图G的一个点集,使得该图中所有边都至少有一个端点在该集合内。

  最小点权覆盖集:在带点权无向图G中,点权之和最小的覆盖集。

  点独立集:无向图G的一个点集,使得任两个在该集合中的点在原图中都不相邻。
  最大点权独立集:在带权无向图G中,点权之和最大的独立集。


  定理:
    1. 最小点权覆盖集=最小割=最大流
    2. 最大点权独立集=总权-最小点权覆盖集

 

  1 #include <cstdio>
  2 #include <climits>
  3 #include <cstring>
  4 #include <queue>
  5 
  6 #define MAXN 20
  7 
  8 const int source = 0;
  9 int n, G[MAXN*MAXN+10][MAXN*MAXN+10], layer[MAXN*MAXN+10], total, sink;
 10 bool vis[MAXN*MAXN+10];
 11 
 12 bool bfs()
 13 {
 14     memset(layer, -1, sizeof(layer));
 15     std::queue<int> q;
 16     q.push(source);
 17     layer[source] = 0;
 18     while(q.empty()==false){
 19         int u = q.front();
 20         q.pop();
 21         for(int v = 1; v <= sink; ++v){
 22             if(layer[v] == -1 && G[u][v] > 0){
 23                 layer[v] = layer[u] + 1;
 24                 if(v == sink)
 25                     return true;
 26                 q.push(v);
 27             }
 28         }
 29     }
 30     return false;
 31 }
 32 
 33 int dinic()
 34 {
 35     int max_flow = 0;
 36     while(bfs() == true){
 37         memset(vis,false,sizeof(vis));
 38         vis[source] = true;
 39         int st[MAXN*MAXN+10];
 40         int top = 0;
 41         st[++top]= source;
 42         while(top > 0) {
 43             int u = st[top];
 44             if(u == sink) {
 45                 int current = INT_MAX;
 46                 int key_path;
 47                 for(int i = 1; i < top; ++i) {
 48                     int s = st[i];
 49                     int e = st[i+1];
 50                     if(current > G[s][e]) {
 51                         current = G[s][e];
 52                         key_path = i;
 53                     }
 54                 }
 55                 for(int i = 1; i < top; ++i) {
 56                     int s = st[i];
 57                     int e = st[i+1];
 58                     G[s][e] -= current;
 59                     G[e][s] += current;
 60                 }
 61 
 62                 max_flow += current;
 63                 while(top > key_path) {
 64                     vis[st[top--]] = false;
 65                 }
 66             }
 67             else {
 68                 int v;
 69                 for(v= 1; v <= sink; ++v) {
 70                     if(layer[v] == layer[u]+1 && vis[v] == false && G[u][v] > 0) {
 71                         vis[v] = true;
 72                         st[++top] = v;
 73                         break;
 74                     }
 75                 }
 76                 if(v == sink+1) {
 77                     top--;
 78                 }
 79             }
 80         }
 81     }
 82     return max_flow;
 83 }
 84 
 85 void init()
 86 {
 87     memset(G, 0, sizeof(G));
 88     total = 0;
 89     sink = n*n+1;
 90     for(int i = 1, input_buffer; i <= n*n; ++i){
 91         scanf("%d", &input_buffer);
 92         total += input_buffer;
 93         int row = (i-0.1) / n + 1;
 94         int column = (i % n == 0) ? (n) : (i % n);
 95         // if (row + column) is odd number, link source to this cell.
 96         if( (row + column)&1 ){
 97             G[source][i] = input_buffer;
 98 
 99             if(i%n != 1)
100                 G[i][i-1] = INT_MAX;
101             if(i%n != 0)
102                 G[i][i+1] = INT_MAX;
103             if(i > n)
104                 G[i][i-n] = INT_MAX;
105             if(i <= n*n-n)
106                 G[i][i+n] = INT_MAX;
107         }
108         // if (row + column) is even number, link this cell to sink.
109         else
110             G[i][sink] = input_buffer;
111     }
112 }
113 
114 int main(int argc, char const *argv[])
115 {
116     // freopen("in", "r", stdin);
117     while(~scanf("%d", &n)){
118         init();
119         printf("%d\n", total - dinic());
120     }
121     return 0;
122 }

 

hdu_1565(网络流)

标签:

原文地址:http://www.cnblogs.com/takeoffyoung/p/4316980.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!