zoukankan      html  css  js  c++  java
  • FZU 2143 Board Game

    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

    5 2 2 9 3 4 2 3 1 3 9 4 6 4 1 1 9 9 3 3 5 1 2 3 4 5 6 7 8 9 3 3 9 1 2 3 4 5 6 7 8 9

     Sample Output

    Case 1: 0 Case 2: 2 Case 3: 81 Case 4: 33 Case 5: 5
      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
    ",++cast, ans + MC.mcmf());
    169     }
    170     return 0;
    171 }
    View Code
  • 相关阅读:
    Java学习笔记三十:Java小项目之租车系统
    Java学习笔记二十九:一个Java面向对象的小练习
    Java学习笔记二十八:Java中的接口
    Java学习笔记二十七:Java中的抽象类
    Java学习笔记二十六:Java多态中的引用类型转换
    Java学习笔记二十五:Java面向对象的三大特性之多态
    Java学习笔记二十四:Java中的Object类
    Java学习笔记二十三:Java的继承初始化顺序
    Java学习笔记二十二:Java的方法重写
    Java学习笔记二十一:Java面向对象的三大特性之继承
  • 原文地址:https://www.cnblogs.com/cyd308/p/4771428.html
Copyright © 2011-2022 走看看