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

hdu 1565 最小割

时间:2015-03-08 10:24:33      阅读:169      评论:0      收藏:0      [点我收藏+]

标签:

 

黑白染色,源指向白,黑指向汇,容量都是方格中数的大小,相邻的格子白指向黑,容量为oo,然后求一次最小割。

这个割是一个简单割,如果只选择不在割中的点,那么一种割就和一个选数方案一一对应,割的大小就是不选的那些数的大小,我们需要最小化这个值。

答案=总和-最小割

 

技术分享
  1 #include <cstdio>
  2 #include <cstring>
  3 #include <queue>
  4 #include <vector>
  5 #define maxn 410
  6 #define oo 0x3f3f3f3f
  7 using namespace std;
  8 
  9 struct Edge {
 10     int u, v, f;
 11     Edge( int u, int v, int f ):u(u),v(v),f(f){}
 12 };
 13 struct Dinic {
 14     int n, src, dst;
 15     vector<Edge> edge;
 16     vector<int> g[maxn];
 17     int dep[maxn], cur[maxn];
 18 
 19     void init( int n, int src, int dst ) {
 20         this->n = n;
 21         this->src = src;
 22         this->dst = dst;
 23         for( int u=1; u<=n; u++ ) 
 24             g[u].clear();
 25         edge.clear();
 26     }
 27     void add_edge( int u, int v, int f ) {
 28         g[u].push_back( edge.size() );
 29         edge.push_back( Edge(u,v,f) );
 30         g[v].push_back( edge.size() );
 31         edge.push_back( Edge(v,u,0) );
 32     }
 33     bool bfs() {
 34         queue<int> qu;
 35         memset( dep, 0, sizeof(dep) );
 36         qu.push( src );
 37         dep[src] = 1;
 38         while( !qu.empty() ) {
 39             int u=qu.front();
 40             qu.pop();
 41             for( int t=0; t<g[u].size(); t++ ) {
 42                 Edge &e = edge[g[u][t]];
 43                 if( e.f && !dep[e.v] ) {
 44                     dep[e.v] = dep[e.u]+1;
 45                     qu.push( e.v );
 46                 }
 47             }
 48         }
 49         return dep[dst];
 50     }
 51     int dfs( int u, int a ) {
 52         if( u==dst || a==0 ) return a;
 53         int remain=a, past=0, na;
 54         for( int &t=cur[u]; t<g[u].size(); t++ ) {
 55             Edge &e = edge[g[u][t]];
 56             Edge &ve = edge[g[u][t]^1];
 57             if( dep[e.v]==dep[e.u]+1 && e.f && (na=dfs(e.v,min(remain,e.f))) ) {
 58                 remain -= na;
 59                 past += na;
 60                 e.f -= na;
 61                 ve.f += na;
 62                 if( !remain ) break;
 63             }
 64         }
 65         return past;
 66     }
 67     int maxflow() {
 68         int flow = 0;
 69         while( bfs() ) {
 70             memset( cur, 0, sizeof(cur) );
 71             flow += dfs(src,oo);
 72         }
 73         return flow;
 74     }
 75 };
 76 
 77 int n, m;
 78 int idx[23][23], id_clock;
 79 int arr[23][23], sum;
 80 int di[4] = { 0, 0, +1, -1 };
 81 int dj[4] = { +1, -1, 0, 0 };
 82 Dinic D;
 83 
 84 int main() {
 85     while( scanf( "%d", &n )==1 ) {
 86         id_clock = 0;
 87         sum = 0;
 88         for( int i=1; i<=n; i++ ) 
 89             for( int j=1; j<=n; j++ ) {
 90                 scanf( "%d", &arr[i][j] );
 91                 sum += arr[i][j];
 92                 idx[i][j] = ++id_clock;
 93             }
 94         D.init( id_clock+2, id_clock+1, id_clock+2 );
 95         for( int i=1; i<=n; i++ )
 96             for( int j=1; j<=n; j++ ) {
 97                 if( (i+j)&1 ) {
 98                     D.add_edge( D.src, idx[i][j], arr[i][j] );
 99                     for( int d=0; d<4; d++ ) {
100                         int ni = i+di[d];
101                         int nj = j+dj[d];
102                         if( 1<=ni&&ni<=n && 1<=nj&&nj<=n ) {
103                             int u = idx[i][j];
104                             int v = idx[ni][nj];
105                             D.add_edge( u, v, oo );
106                         }
107                     }
108                 } else {
109                     D.add_edge( idx[i][j], D.dst, arr[i][j] );
110                 }
111             }
112         printf( "%d\n", sum-D.maxflow() );
113     }
114 }
View Code

 

hdu 1565 最小割

标签:

原文地址:http://www.cnblogs.com/idy002/p/4321308.html

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