[ SDOI 2016 ] 牆上的句子
阿新 • • 發佈:2021-07-14
題目
思路
程式碼
#include <iostream> #include <cstring> #include <algorithm> #include <map> #include <set> using namespace std; const int N = 1010, M = N * N, INF = 1e9; int Cases, n, m, S, T, col[N], row[N], cnt; int h[N], t[M], p[M], f[M], idx; char g[N][N]; void add(int a, int b, int c) { f[idx] = c, t[idx] = b, p[idx] = h[a], h[a] = idx++; } void add(int a, int b, int c, int d) { add(a, b, c), add(b, a, d); } map<string, int> id; set<string> same; void Process(string str, int type, int x) { int n = str.size(), flag; for (int i = 0, r; i < n; i = r) { if (str[i] == '_') { r = i + 1; continue; } for (r = i; (r < n && str[r] != '_'); r++); string a = str.substr(i, r - i); string b = a; reverse(b.begin(), b.end()); (b < a) ? swap(a, b), flag = -1 : flag = 1; if (a == b) { same.insert(a); continue; } if (!id.count(a)) id[a] = ++cnt, id[b] = ++cnt, add(id[a], id[b], 2, 0); flag *= type; if (flag == 1) add(S, id[a], INF, 0); if (flag == -1) add(id[b], T, INF, 0); if (flag == 0) add(id[b], x, INF, 0), add(x, id[a], INF, 0); } } int d[N], cur[N], q[N]; bool BFS() { int hh = 0, tt = -1; memset(d, -1, sizeof d); d[S] = 0, q[++tt] = S, cur[S] = h[S]; while (hh <= tt) { int u = q[hh++]; for (int i = h[u], v; v = t[i], i != -1; i = p[i]) { if (d[v] != -1 || !f[i]) continue; d[v] = d[u] + 1, cur[v] = h[v], q[++tt] = v; if (v == T) return true; } } return false; } int DFS(int u, int limit) { if (u == T) return limit; int flow = 0; for (int i = cur[u], v; v = t[i], i != -1 && flow < limit; i = p[i]) { cur[u] = i; if (d[v] == d[u] + 1 && f[i]) { int t = DFS(v, min(f[i], limit - flow)); if (!t) d[v] = -1; f[i] -= t, f[i ^ 1] += t, flow += t; } } return flow; } int Dinic() { int flow = 0, res = 0; while (BFS()) while (flow = DFS(S, INF)) res += flow; return res; } int main() { cin >> Cases; while (Cases--) { memset(h, -1, sizeof h), idx = 0; same.clear(), id.clear(); cin >> n >> m; S = 1, T = 2, cnt = 2 + n + m; for (int i = 1; i <= n; i++) cin >> row[i]; for (int i = 1; i <= m; i++) cin >> col[i]; for (int i = 1; i <= n; i++) cin >> g[i] + 1; string str; for (int i = 1; i <= n; i++) // row str = g[i] + 1, Process(str, row[i], i + 2); for (int i = 1; i <= m; i++) { // col str.clear(); for (int j = 1; j <= n; j++) str += g[j][i]; Process(str, col[i], i + n + 2); } cout << Dinic() + same.size() << endl; } return 0; }