您的位置:首页 > 其它

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 ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: