BZOJ 1475: 方格取数( 网络流 )
2015-07-15 23:47
627 查看
本来想写道水题....结果调了这么久!就是一个 define 里面少加了个括号 !
二分图最大点权独立集...黑白染色一下 , 然后建图 :
S -> black_node , white_node -> T , 流量都为点权 . 然后 black_node -> white_node ( 两点有公共边 ) , 流量为 +oo , 然后 answer = ∑ w( i ) ( i ∈ V ) - maxflow
-------------------------------------------------------------------------------------------------
#include<cstdio>#include<cstring>#include<algorithm>#include<iostream> #define rep( i , n ) for( int i = 0 ; i < n ; ++i )#define clr( x , c ) memset( x , c , sizeof( x ) )#define id( x , y ) ( ( x ) * n + y + 1 ) using namespace std; const int inf = 0x7fffffff;const int maxn = 1000; struct edge { int to , cap; edge *next , *rev;} E[ maxn << 3 ] , *pt = E , *head[ maxn ]; inline void add_edge( int u , int v , int w ) { pt -> to = v; pt -> cap = w; pt -> next = head[ u ]; head[ u ] = pt++; pt -> to = u; pt -> cap = 0; pt -> next = head[ v ]; head[ v ] = pt++; head[ u ] -> rev = head[ v ]; head[ v ] -> rev = head[ u ];} int h[ maxn ] , cnt[ maxn ] , S , T , N;edge *cur[ maxn ] , *p[ maxn ]; int maxFlow() { clr( h , 0 ) , clr( cnt , 0 ); cnt[ 0 ] = N; rep( i , N ) cur[ i ] = head[ i ]; int flow = 0 , A = inf; edge* e; for( int x = S ; h[ S ] < N ; ) { for( e = cur[ x ] ; e ; e = e -> next ) if( h[ e -> to ] + 1 == h[ x ] && e -> cap ) break; if( e ) { A = min( A , e -> cap ); p[ e -> to ] = cur[ x ] = e; if( ( x = e -> to ) == T ) { for( ; x != S ; x = p[ x ] -> rev -> to ) { p[ x ] -> cap -= A; p[ x ] -> rev -> cap += A; } flow += A; A = inf; } } else { if( ! --cnt[ h[ x ] ] ) break; h[ x ] = N; for( e = head[ x ] ; e ; e = e -> next ) if( e -> cap && h[ e -> to ] + 1 < h[ x ] ) { h[ x ] = h[ e -> to ] + 1; cur[ x ] = e; } cnt[ h[ x ] ]++; if( x != S ) x = p[ x ] -> rev -> to; } } return flow;} int main(){ freopen( "test.in" , "r" , stdin ); clr( head , 0 ); int ans = 0 , n; cin >> n; S = 0 , T = n * n + 1 , N = T + 1; rep( i , n ) rep( j , n ) { int w; scanf( "%d" , &w ); ans += w; if( ( i + j ) & 1 ) { add_edge( S , id( i , j ) , w ); if( i ) add_edge( id( i , j ) , id( i - 1 , j ) , inf ); if( j ) add_edge( id( i , j ) , id( i , j - 1 ) , inf ); if( i + 1 < n ) add_edge( id( i , j ) , id( i + 1 , j ) , inf ); if( j + 1 < n ) add_edge( id( i , j ) , id( i , j + 1 ) , inf ); } else add_edge( id( i , j ) , T , w ); } cout << ans - maxFlow() << "\n"; return 0;}
-------------------------------------------------------------------------------------------------
1475: 方格取数
Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 616 Solved: 323
[Submit][Status][Discuss]
Description
在一个n*n的方格里,每个格子里都有一个正整数。从中取出若干数,使得任意两个取出的数所在格子没有公共边,且取出的数的总和尽量大。Input
第一行一个数n;(n<=30) 接下来n行每行n个数描述一个方阵Output
仅一个数,即最大和Sample Input
21 2
3 5
Sample Output
6HINT
Source
相关文章推荐
- java网络编程(2)——UDP与TCP
- HTTP 协议漫谈
- android-async-http源码解析
- 【android安全】之使用ssl验证保护网络数据传输安全。
- HttpServletRequest对象(一)
- Java HttpClient使用
- Windows Azure 保留已存在的虚拟网络外网IP(云服务)
- HttpServletResponse对象(二)
- HttpServletResponse对象(一)
- centos 重启网站服务器 httpd
- java网络编程(1)
- Android网络框架-Volley(五) 使用Volley发送自定义Request
- 腾讯电脑管家(QQ电脑管家)劫持IE开始页至 http://guanjia.qq.com/comm-htdocs/quickaccess/ 的处理
- 黑马程序员_网络编程概述
- iOS 通过网络请求获取图片的下载歌曲
- linux系统网络命令(三)
- Http的GET和POST请求
- http权威指南笔记第二章URL
- Http协议原理(一)
- Network:socket发送http请求