zoukankan      html  css  js  c++  java
  • Codeforces 436C

    题目链接

    C. Dungeons and Candies
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    During the loading of the game "Dungeons and Candies" you are required to get descriptions of k levels from the server. Each description is a map of an n × m checkered rectangular field. Some cells of the field contain candies (each cell has at most one candy). An empty cell is denoted as "." on the map, but if a cell has a candy, it is denoted as a letter of the English alphabet. A level may contain identical candies, in this case the letters in the corresponding cells of the map will be the same.

    When you transmit information via a network, you want to minimize traffic — the total size of the transferred data. The levels can be transmitted in any order. There are two ways to transmit the current level A:

    1. You can transmit the whole level A. Then you need to transmit n·m bytes via the network.
    2. You can transmit the difference between level A and some previously transmitted level B (if it exists); this operation requires to transmit dA, B·w bytes, where dA, B is the number of cells of the field that are different for A and B, and w is a constant. Note, that you should compare only the corresponding cells of levels A and B to calculate dA, B. You cannot transform the maps of levels, i.e. rotate or shift them relatively to each other.

    Your task is to find a way to transfer all the k levels and minimize the traffic.

    Input

    The first line contains four integers n, m, k, w (1 ≤ n, m ≤ 10; 1 ≤ k, w ≤ 1000). Then follows the description of k levels. Each level is described by n lines, each line contains m characters. Each character is either a letter of the English alphabet or a dot ("."). Please note that the case of the letters matters.

    Output

    In the first line print the required minimum number of transferred bytes.

    Then print k pairs of integers x1, y1, x2, y2, ..., xk, yk, describing the way to transfer levels. Pair xi, yi means that level xi needs to be transferred by way yi. If yi equals 0, that means that the level must be transferred using the first way, otherwise yi must be equal to the number of a previously transferred level. It means that you will transfer the difference between levels yi and xi to transfer level xi. Print the pairs in the order of transferring levels. The levels are numbered 1 through k in the order they follow in the input.

    If there are multiple optimal solutions, you can print any of them.

    Sample test(s)
    Input
    2 3 3 2
    A.A
    ...
    A.a
    ..C
    X.Y
    ...
    Output
    14
    1 0
    2 1
    3 1
    Input
    1 1 4 1
    A
    .
    B
    .
    Output
    3
    1 0
    2 0
    4 2
    3 0
    Input
    1 3 5 2
    ABA
    BBB
    BBA
    BAB
    ABB
    Output
    11
    1 0
    3 1
    2 3
    4 2
    5 1

    解题思路: 以第i个level为结点i, 并增加一个0作为采用第一种方式上传level, 每个点(1...k)到标记为0的点的边权为n * m, 
          其他从i点到j点的边权为diff(level i, level j), 也就是第i个level和第j个level不同的个数,
          然后求一遍MST(最小生成树)即可。
    Accepted Code:
     1 /*************************************************************************
     2     > File Name: 436C.cpp
     3     > Author: Stomach_ache
     4     > Mail: sudaweitong@gmail.com
     5     > Created Time: 2014年06月24日 星期二 17时03分36秒
     6     > Propose: 
     7  ************************************************************************/
     8 
     9 #include <cmath>
    10 #include <string>
    11 #include <cstdio>
    12 #include <vector>
    13 #include <fstream>
    14 #include <cstring>
    15 #include <iostream>
    16 #include <algorithm>
    17 using namespace std;
    18 
    19 #define INF (0x3f3f3f3f)
    20 int n, m, k, w;
    21 char a[1002][12][12];
    22 int cost[1002][1002], d[1002], from[1002];
    23 bool used[1002];
    24 vector<int> OoO;
    25 
    26 int
    27 dist(int x, int y) {
    28       int cnt = 0;
    29       for (int i = 0; i < n; i++) 
    30           for (int j = 0; j < m; j++)
    31               if (a[x][i][j] != a[y][i][j]) cnt++;
    32     return cnt;
    33 }
    34 
    35 int
    36 main(void) {
    37       ios_base::sync_with_stdio(false);
    38       while (~scanf("%d %d %d %d", &n, &m, &k, &w)) {
    39           for (int i = 1; i <= k; i++)
    40               for (int j = 0; j < n; j++) scanf("%s", a[i][j]);
    41         
    42         for (int i = 1; i <= k; i++) {
    43               for (int j = i+1; j <= k; j++) {
    44                   cost[i][j] = cost[j][i] = dist(i, j) * w;
    45             }
    46             cost[i][0] = cost[0][i] = m * n;
    47         }
    48         memset(used, false, sizeof(used));
    49         memset(d, 0x3f, sizeof(d));
    50         d[0] = 0;
    51         int ans = 0;
    52         OoO.clear();
    53         while (true) {
    54               int v = -1;
    55             for (int u = 0; u <= k; u++) {
    56                   if (!used[u] && (v==-1 || d[v] > d[u])) {
    57                       v = u;
    58                 }
    59             }
    60             if (v == -1) break;
    61             used[v] = true;
    62             ans += d[v];
    63             for (int u = 0; u <= k; u++) if (!used[u] && d[u] > cost[u][v]){
    64                   d[u] = cost[u][v];
    65                 from[u] = v;
    66             }
    67             OoO.push_back(v);
    68         }
    69         printf("%d
    ", ans);
    70         for (int i = 1; i <= k; i++) {
    71               printf("%d %d
    ", OoO[i], from[OoO[i]]);
    72         }
    73     }
    74 
    75     return 0;
    76 }


    
    

    
    

    
    

    
    

    
    

  • 相关阅读:
    第一次博客作业
    自我介绍
    第一次个人编程作业
    第一次博客作业
    第一次个人编程作业
    第一次博客作业
    Alpha冲刺
    Alpha冲刺 (2/10)
    Alpha 冲刺 (1/10)
    福大软工 · 第七次作业
  • 原文地址:https://www.cnblogs.com/Stomach-ache/p/3806700.html
Copyright © 2011-2022 走看看