Language: C++

#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <iostream>
#include <sstream>
#include <algorithm>
using namespace std;

struct edge {
    int to, cap, cost, rev;
};
int V;
vector<edge> G[802];
int dist[802];
int prevv[802], preve[802];

void add_edge(int from, int to, int cap, int cost) {
    G[from].push_back((edge){to, cap, cost, G[to].size()});
    G[to].push_back((edge){from, 0, -cost, G[from].size() - 1});
}

const int INF = 10000000;
int min_cost_flow(int s, int t, int f) {
    int res = 0;
    while (f > 0) {
        fill(dist, dist + V, INF);
        dist[s] = 0;
        bool update = true;
        while (update) {
            update = false;
            for (int v = 0; v < V; ++v) {
                if (dist[v] == INF) continue;
                for (int i = 0; i < G[v].size(); ++i) {
                    edge &e = G[v][i];
                    if (e.cap > 0 && dist[e.to] > dist[v] + e.cost) {
                        dist[e.to] = dist[v] + e.cost;
                        prevv[e.to] = v;
                        preve[e.to] = i;
                        update = true;
                    }
                }
            }
        }

        if (dist[t] == INF)
            return -1;

        int d = f;
        for (int v = t; v != s; v = prevv[v])
            d = min(d, G[prevv[v]][preve[v]].cap);
        f -= d;
        res += d * dist[t];
        for (int v = t; v != s; v = prevv[v]) {
            edge &e = G[prevv[v]][preve[v]];
            e.cap -= d;
            G[v][e.rev].cap += d;
        }
    }
    return res;
}

int edist(string s1, string s2)
{
    int d[21][21];
    for (int i = 0; i < 21; ++i)
        d[i][0] = d[0][i] = i;

    for (int i = 1; i <= s1.size(); ++i) {
        for (int j = 1; j <= s2.size(); ++j) {
            int cost = s1[i - 1] != s2[j - 1];
            d[i][j] = min(min(
                    d[i - 1][j] + 1,
                    d[i][j - 1] + 1),
                    d[i - 1][j - 1] + cost);
        }
    }
    return d[s1.size()][s2.size()];
}

int main()
{
    int n, m;
    scanf("%d %d ", &n, &m);

    map<string, int> t;
    for (int i = 0; i < n; ++i) {
        char buf[1002];
        gets(buf);

        istringstream s(buf);
        string w;
        while (getline(s, w, ' '))
            ++t[w];
    }
    vector<string> ts;
    vector<int> ti;
    for (auto it = t.begin(); it != t.end(); ++it) {
        ts.push_back(it->first);
        ti.push_back(it->second);
    }

    vector<string> w(m);
    for (int i = 0; i < m; ++i) {
        char buf[22];
        scanf("%s", buf);
        w[i] = buf;
    }

    for (int i = 0; i < ts.size(); ++i)
        add_edge(0, i + 2, 1, 0);
    for (int j = 0; j < w.size(); ++j)
        add_edge(j + 2 + ts.size(), 1, 1, 0);

    for (int i = 0; i < ts.size(); ++i) {
        for (int j = 0; j < w.size(); ++j) {
            add_edge(i + 2, j + 2 + ts.size(), 1, edist(ts[i], w[j]) * ti[i]);
        }
    }

    V = 2 + ts.size() + w.size();
    int ans = min_cost_flow(0, 1, ts.size());
    printf("%d\n", ans);

    return 0;
}

Compiler output:
a.cc: In function 'void add_edge(int, int, int, int)':
a.cc:20:55: warning: narrowing conversion of 'G[to].std::vector<edge>::size()' from 'std::vector<edge>::size_type' {aka 'long unsigned int'} to 'int' [-Wnarrowing]
   20 |     G[from].push_back((edge){to, cap, cost, G[to].size()});
      |                                             ~~~~~~~~~~^~
a.cc:21:59: warning: narrowing conversion of '(G[from].std::vector<edge>::size() - 1)' from 'std::vector<edge>::size_type' {aka 'long unsigned int'} to 'int' [-Wnarrowing]
   21 |     G[to].push_back((edge){from, 0, -cost, G[from].size() - 1});
      |                                            ~~~~~~~~~~~~~~~^~~
a.cc: In function 'int main()':
a.cc:90:9: error: 'gets' was not declared in this scope; did you mean 'getw'?
   90 |         gets(buf);
      |         ^~~~
      |         getw