FZU 2143 Board Game
Accept: 95 Submit: 246
Time Limit: 1000 mSec Memory Limit : 32768 KB
Problem Description
Fat brother and Maze are playing a kind of special (hentai) game on an N*M board (N rows, M columns). At the beginning, each grid of the board which is own by Fat brother is consisting of an integer 0. At each turn, he can choose two adjacent grids and add both the integer inside them by 1. But due to some unknown reason, the number of each grid can not be large than a given integer K. Also, Maze has already drown an N*M board with N*M integers inside each grid. What Fat brother would like to do is adding his board to be as same as Maze’s. Now we define the different value of two boards A and B as:
Now your task is to help Fat brother the minimal value of S he can get.
Input
The first line of the date is an integer T, which is the number of the text cases.
Then T cases follow, each case contains three integers N, M and K which are mention above. Then N lines with M integers describe the board.
1 <= T <= 100, 1 <= N, M, K <= 9
0 <= the integers in the given board <= 9
Output
For each case, output the case number first, then output the minimal value of S Fat brother can get.
Sample Input
Sample Output
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <queue> 6 using namespace std; 7 8 const int E = 50010; 9 const int oo = 0x7fffffff; 10 const int inf = 10000; 11 const int maxn = 1010; 12 13 struct edge 14 { 15 int next,v,flow,cost; 16 } e[E]; 17 18 struct MCMF 19 { 20 int head[maxn]; 21 queue<int> q; 22 int cnt, S, T; 23 void init(int __S,int __T) 24 { 25 S = __S; 26 T = __T; 27 memset(head,-1,sizeof(head)); 28 cnt = 0; 29 } 30 void add(int u,int v,int flow,int cost) 31 { 32 e[cnt].v = v; 33 e[cnt].flow = flow; 34 e[cnt].cost = cost; 35 e[cnt].next = head[u]; 36 head[u] = cnt ++; 37 } 38 39 void AddEdge(int u,int v,int flow,int cost) 40 { 41 add(u,v,flow,cost); 42 add(v,u,0, -cost); 43 } 44 45 46 47 int dis[maxn],cc[maxn],visit[maxn],pre[maxn],dd[maxn]; 48 49 int spfa() 50 { 51 fill(dis,dis + T + 1, oo); 52 dis[S] = 0; 53 pre[S] = -1; 54 q.push(S); 55 while(!q.empty()) 56 { 57 int u = q.front(); 58 q.pop(); 59 visit[u] = 0; 60 for(int i = head[u]; i != -1; i = e[i].next) 61 { 62 if(e[i].flow > 0 && dis[e[i].v] > dis[u] + e[i].cost) 63 { 64 dis[e[i].v] = dis[u] + e[i].cost; 65 pre[e[i].v] = u; 66 cc[e[i].v] = i; 67 dd[e[i].v] = e[i].cost; 68 if(!visit[e[i].v]) 69 { 70 q.push(e[i].v); 71 visit[e[i].v] = 1; 72 } 73 } 74 } 75 } 76 return dis[T] < 0; 77 } 78 79 int argument() 80 { 81 int aug = oo; 82 int u,v; 83 int ans = 0; 84 for(u = pre[v = T]; v != S; v = u, u = pre[v]) 85 if(e[cc[v]].flow < aug) aug = e[cc[v]].flow; 86 for(u = pre[v = T]; v != S; v = u, u = pre[v]) 87 { 88 e[cc[v]].flow -= aug; 89 e[cc[v] ^ 1].flow += aug; 90 ans += dd[v] * aug; 91 } 92 return ans; 93 } 94 95 int mcmf() 96 { 97 int res = 0; 98 memset(visit,0,sizeof(visit)); 99 while(spfa()) res += argument(); 100 return res; 101 } 102 } MC; 103 104 105 int N,M,K; 106 int b[11][11]; 107 108 int main() 109 { 110 int cas, cast = 0; 111 scanf("%d",&cas); 112 while (cas--) 113 { 114 scanf("%d%d%d",&N,&M,&K); 115 for (int i=1;i<=N;i++) 116 { 117 for (int j=1;j<=M;j++) 118 { 119 scanf("%d",&b[i][j]); 120 } 121 } 122 123 124 int nn = N * M + 2, s = 0, t = N*M + 1; 125 MC.init(s,t); 126 int ans = 0; 127 for (int i=1;i<=N;i++) 128 for (int j=1;j<=M;j++) 129 { 130 ans += b[i][j] * b[i][j]; 131 int p = i*M - M + j; 132 if ((i+j)%2==0){ 133 for (int k=1;k<=K;k++) 134 { 135 int tmp = 2 * k - 1 - 2 * b[i][j]; 136 MC.AddEdge(s,p, 1,tmp); 137 } 138 int pp = 0; 139 if (i<N) 140 { 141 pp = p + M; 142 MC.AddEdge(p,pp,inf,0); 143 } 144 if (i>1) 145 { 146 pp = p - M; 147 MC.AddEdge(p,pp,inf,0); 148 } 149 if (j<M) 150 { 151 pp = p + 1; 152 MC.AddEdge(p,pp,inf,0); 153 } 154 if (j>1) 155 { 156 pp = p - 1; 157 MC.AddEdge(p,pp,inf,0); 158 } 159 }else{ 160 for (int k=1;k<=K;k++) 161 { 162 int tmp = 2 * k - 1 - 2 * b[i][j]; 163 MC.AddEdge(p,t, 1,tmp); 164 } 165 } 166 } 167 // MC.AddEdge(s,t,INF,0); 168 printf("Case %d: %d\n",++cast, ans + MC.mcmf()); 169 } 170 return 0; 171 }