题目传送门
sol:根据题意建立流量网络然后跑网络流,这两天刚学的网络流,练练手。
- 网络最大流
#include <bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int, int> PII; const int INF = 0x3f3f3f3f; map<int, int> mp; char ss[2000010]; struct { int v, w, n; } edge[2010]; int head[2010], tot; int dis[2010]; int s, t; void add_edge(int u, int v, int w) { int i = tot ++; edge[i].v = v; edge[i].w = w; edge[i].n = head[u]; head[u] = i; } bool bfs() { queue<int> que; memset(dis, -1, sizeof(dis)); dis[t] = 0; que.push(t); while (!que.empty()) { int u = que.front(); que.pop(); for (int i = head[u]; i != -1; i = edge[i].n) { int v = edge[i].v, w = edge[i ^ 1].w; if (dis[v] != -1 || w == 0) continue; dis[v] = dis[u] + 1; que.push(v); } } return dis[s] != -1; } int dfs(int u, int k) { if (u == t) return k; for (int i = head[u]; i != -1; i = edge[i].n) { int v = edge[i].v, w = edge[i].w; if (dis[v] + 1 == dis[u] && w) { int k = dfs(v, min(k, w)); if (k > 0) { edge[i].w -= k; edge[i ^ 1].w += k; return k; } } } return 0; } bool slove() { int c[10]; memset(c, 0, sizeof(c)); memset(head, -1, sizeof(head)); tot = 0; scanf("%s", ss); for (int i = 0; ss[i]; i++) c[ss[i] ^ '0'] ++; s = 0, t = mp.size() + 10; for (int i = 1; i < 10; i++) { if (c[i]) { add_edge(s, i, c[i]); add_edge(i, s, 0); } } int index = 10; for (auto p : mp) { for (int i = 1; i < 10; i++) { if (p.first & (1 << i)) { add_edge(i, index, p.second); add_edge(index, i, 0); } } add_edge(index, t, p.second); add_edge(t, index, 0); index ++; } int res = 0; while (bfs()) res += dfs(s, INF); return res == strlen(ss); } int main() { int n, m; scanf("%d%d%*c", &n, &m); for (int i = 1; i <= n; i++) { int k = 0; for (int j = 1; j <= 6; j++) k |= 1 << (getchar() ^ '0'); mp[k] ++; getchar(); } for (int i = 1; i <= m; i++) puts(slove() ? "dyf" : "zzk"); return 0; }