fzu2143
2016-04-21 18:29
302 查看
#include <iostream> #include <string> #include <string.h> #include <vector> #include <stdio.h> #include <algorithm> #include <map> #include <queue> #include <limits.h> typedef long long LL ; const int MAXN = 1010; const int MAXM = 10010; const int INF = 0x3f3f3f3f; struct Edge { int to,next,cap,flow,cost; }edge[MAXM]; int head[MAXN],tol; int pre[MAXN],dis[MAXN]; bool vis[MAXN]; int N; void init(int n) { N = n; tol = 0; memset(head,-1,sizeof(head)); } void addedge(int u,int v,int cap,int cost) { edge[tol].to = v; edge[tol].cap = cap; edge[tol].cost = cost; edge[tol].flow = 0; edge[tol].next = head[u]; head[u] = tol++; edge[tol].to = u; edge[tol].cap = 0; edge[tol].cost = -cost; edge[tol].flow = 0; edge[tol].next = head[v]; head[v] = tol++; } bool spfa(int s,int t) { std::queue<int>q; for(int i = 0 ; i < N ; i++){ dis[i] = INF ; vis[i] = false ; pre[i] = -1 ; } dis[s] = 0 ; vis[s] = true ; q.push(s) ; while(! q.empty()){ int u = q.front() ; q.pop() ; vis[u] = false ; for(int i = head[u] ; i != -1 ; i = edge[i].next){ int v = edge[i].to ; if(edge[i].cap > edge[i].flow && dis[v] > dis[u] + edge[i].cost){ dis[v] = dis[u] + edge[i].cost ; pre[v] = i ; if(! vis[v]){ vis[v] = true; q.push(v); } } } } return dis[t] < 0 ; // if(pre[t] == -1)return false; //找不到一条增广路径 // else return true; } std::pair<int , int> minCostMaxflow(int s,int t){ int flow = 0; int cost = 0; while(spfa(s , t)){ int Min = INF ; for(int i = pre[t] ; i != -1 ; i = pre[edge[i^1].to]) Min = std::min(Min , edge[i].cap - edge[i].flow) ; for(int i = pre[t] ; i != -1 ; i = pre[edge[i^1].to]){ edge[i].flow += Min; edge[i^1].flow -= Min; cost += edge[i].cost * Min ; } flow += Min ; } return std::make_pair(cost , flow) ; } int n , m ; int idx(int x , int y){ return m * (x - 1) + y ; } int b[18][18] ; int dir[4][2] = {{-1,0},{0,-1},{1,0},{0,1}} ; int can(int x , int y){ return 1 <= x && x <= n && 1 <= y && y <= m ; } int main(){ int t , K , res ; scanf("%d" , &t) ; for(int ca = 1 ; ca <= t ; ca++){ scanf("%d%d%d" , &n , &m , &K) ; int st = 0 ; int ed = n*m+1 ; init(ed+1) ; res = 0 ; for(int i = 1 ; i <= n ; i++){ for(int j = 1 ; j <= m ; j++){ scanf("%d" , &b[i][j]) ; res += b[i][j] * b[i][j] ; } } for(int i = 1 ; i <= n ; i++){ for(int j = 1 ; j <= m ; j++){ int u = idx(i , j) ; if(((i+j)%2) == 0){ for(int k = 1 ; k <= K ; k++){ addedge(st , u , 1 , 2*k-1-2*b[i][j]) ; } for(int k = 0 ; k < 4 ; k++){ int x = i + dir[k][0] ; int y = j + dir[k][1] ; if(can(x,y)) addedge(u , idx(x,y) , INF , 0) ; } } else{ for(int k = 1 ; k <= K ; k++){ addedge(u , ed , 1 , 2*k-1-2*b[i][j]) ; } } } } printf("Case %d: %d\n" , ca , res + minCostMaxflow(st , ed).first) ; } return 0 ; }
相关文章推荐
- APUE------进程控制
- hdu 1788 最小公倍数(这题面。。。)
- HDOJ 3415 Max Sum of Max-K-sub-sequence
- Codeforces 554C Kyoya and Colored Balls 【dp + 组合数学】
- ViewFlipper的功能和用法
- Runtime 无法执行多个cmd命令问题
- Oracle 数据导入导出 imp/exp
- Html学习笔记3
- Android 重写ScrollView控件,以至于上下拖动时获取正确的滚动位置
- 解决apache启动错误:Could not reliably determine the server's fully qualified domain name
- freemarker中使用shiro标签
- Codeforces 554B Ohana Cleans Up 【水题】
- Android Overdraw
- 转:车牌的自动截取与识别方案
- openstack数据库获取一个虚机的floating_ip, fix_ip, project_name, user_name, hostname, host
- 在虚拟机中搭建CDH版本的大数据平台
- 华为 S5700S-28P-LI配置IP、基础命令及学习资料
- Codeforces 554A Kyoya and Photobooks 【水题】
- 有关npm rum的3个简洁技巧
- receiver type "className" for instance message is a forward declaration