思路是对于每个人遍历志愿,找有增广前途的导师,第一问大概是没有 WA 的(可以看见我的提交记录都是 WA on 偶数行)。
第二问的处理方法是再处理第一问的时候记录每一个导师在收入第几个学生后还有增广前途,把后面的学生放在这个学生戳后即可。
现在 WA 30pts,对的挺多的大概是细节问题,求调,STO
flow::mf_graph
计算最大流是没问题的,而且运行完其 ::max_flow()
后保证其 ::dis
为那个做 BFS 的结果(-1
表示无增广前途,也就是说非 -1
的点若后面有路可以去汇点,则可以继续增广,这是显然的因为 dis
非 -1
代表可以由源点来)。
非必要请从 928 行开始阅读程序。
// Problem: P4382 [八省联考 2018] 劈配
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P4382
// Memory Limit: 500 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
//#include <bits/extc++.h>
#define multiple_cases(T, C) signed T, C; cin >> T >> C; while (T--)
#define variable_name(x) #x
#define vdebug(x) variable_name(x) << " = " << x
#define pdebug(x) "*" << variable_name(x) << " = " << *(x)
#define all(x) (x).begin(), (x).end()
using namespace std;
//using namespace __gnu_cxx;
//using namespace __gnu_pbds;
const int mod = 998244353;
template<typename T, typename Tb>
T quickpower(T a, Tb b) {
if (b < 0) b = b % (mod - 1) + mod - 1;
T c = 1;
while (b) {
if (b & 1) {
c *= a;
c %= mod;
}
a *= a;
a %= mod;
b >>= 1;
}
return c;
}
template<typename T, typename Tb>
T auto_quickpower(T a, Tb b) {
T c = 1;
while (b) {
if (b & 1) {
c *= a;
}
a *= a;
b >>= 1;
}
return c;
}
namespace quick_io {
#define quick_io_int_length_limit 128
#define quick_io_int_radix_type size_t
#define quick_io_length_type size_t
bool is_digit[128];
quick_io_int_radix_type quick_io_int_radix = 10;
quick_io_int_radix_type cur_int_radix = 0;
char __quick_io_d2c(size_t a) {
if (a <= 9) {
return '0' + a;
} else if (a <= 35) {
return 'A' + a - 10;
} else {
return 'a' + a - 36;
}
}
size_t __quick_io_c2d(char a) {
if (a >= '0' && a <= '9') {
return a - '0';
} else if (a >= 'A' && a <= 'Z') {
return a - 'A' + 10;
} else /*if (a >= 'a' && a <= 'z')*/ {
return a - 'a' + 36;
}
}
struct quick_io_change_int_radix {
quick_io_change_int_radix(quick_io_int_radix_type now_int_radix = quick_io_int_radix) {
if (cur_int_radix == now_int_radix) return;
cur_int_radix = quick_io_int_radix = now_int_radix;
memset(is_digit, 0, sizeof(is_digit));
for (size_t i = 0; i < now_int_radix; i++) {
is_digit[size_t(__quick_io_d2c(i))] = true;
}
}
} set_radix;
template<typename T>
void print(T a, string s = " ") {
for (auto i : a) {
cout << i << s;
}
}
ostream &operator<<(ostream &A, __int128 b) {
char a[128], k = 0;
memset(a, 0, sizeof(a));
quick_io_length_type pos = 0;
if (b < 0) k = -1, b = -b;
while (b) {
a[pos++] = __quick_io_d2c(b % quick_io_int_radix);
b /= quick_io_int_radix;
}
if (!~k) {
a[pos++] = '-';
}
if (!pos) {
a[pos++] = '0';
}
reverse(a, a + pos);
return A << a;
}
istream &operator>>(istream &A, __int128 &b) {
int k = 1;
char c = getchar();
b = 0;
while (c != '-' && !is_digit[size_t(c)]) {
c = getchar();
}
if (c == '-') {
k = -1;
c = getchar();
}
while (is_digit[size_t(c)]) {
b = b * quick_io_int_radix + __quick_io_c2d(c);
c = getchar();
}
if (!~k) b = -b;
return A;
}
template<typename T>
ostream &operator<<(ostream &A, const vector<T> &b);
template<typename T1, typename T2>
ostream &operator<<(ostream &A, const pair<T1, T2> &b);
template<typename T>
ostream &operator<<(ostream &A, const set<T> &b);
template<typename T>
ostream &operator<<(ostream &A, const multiset<T> &b);
template<typename T, typename T2>
ostream &operator<<(ostream &A, const map<T, T2> &b);
template<typename T, typename T2>
ostream &operator<<(ostream &A, const multimap<T, T2> &b);
template<typename T>
ostream &operator<<(ostream &A, const unordered_set<T> &b);
template<typename T>
ostream &operator<<(ostream &A, const unordered_multiset<T> &b);
template<typename T, typename T2>
ostream &operator<<(ostream &A, const unordered_map<T, T2> &b);
template<typename T, typename T2>
ostream &operator<<(ostream &A, const unordered_multimap<T, T2> &b);
template<typename T>
ostream &operator<<(ostream &A, const vector<T> &b) {
A << "[";
for (size_t i = 0; i + 1 < b.size(); i++) {
A << b[i] << ",";
}
if (b.size()) {
A << b[b.size() - 1];
}
A << "]";
return A;
}
template<typename T1, typename T2>
ostream &operator<<(ostream &A, const pair<T1, T2> &b) {
return A << '(' << b.first << ',' << b.second << ')';
}
template<typename T>
ostream &operator<<(ostream &A, const set<T> &b) {
typename set<T>::const_iterator i = b.begin(), e = b.end();
A << "{";
while (i != e) {
A << *i;
i++;
if (i != e) {
A << ",";
}
}
return A << "}";
}
template<typename T>
ostream &operator<<(ostream &A, const multiset<T> &b) {
typename multiset<T>::const_iterator i = b.begin(), e = b.end();
A << "{";
while (i != e) {
A << *i;
i++;
if (i != e) {
A << ",";
}
}
return A << "}";
}
template<typename T, typename T2>
ostream &operator<<(ostream &A, const map<T, T2> &b) {
typename map<T, T2>::const_iterator i = b.begin(), e = b.end();
A << "{";
while (i != e) {
A << *i;
i++;
if (i != e) {
A << ",";
}
}
return A << "}";
}
template<typename T, typename T2>
ostream &operator<<(ostream &A, const multimap<T, T2> &b) {
typename multimap<T, T2>::const_iterator i = b.begin(), e = b.end();
A << "{";
while (i != e) {
A << *i;
i++;
if (i != e) {
A << ",";
}
}
return A << "}";
}
template<typename T>
ostream &operator<<(ostream &A, const unordered_set<T> &b) {
typename unordered_set<T>::const_iterator i = b.begin(), e = b.end();
A << "{";
while (i != e) {
A << *i;
i++;
if (i != e) {
A << ",";
}
}
return A << "}";
}
template<typename T>
ostream &operator<<(ostream &A, const unordered_multiset<T> &b) {
typename unordered_multiset<T>::const_iterator i = b.begin(), e = b.end();
A << "{";
while (i != e) {
A << *i;
i++;
if (i != e) {
A << ",";
}
}
return A << "}";
}
template<typename T, typename T2>
ostream &operator<<(ostream &A, const unordered_multimap<T, T2> &b) {
typename unordered_multimap<T, T2>::const_iterator i = b.begin(), e = b.end();
A << "{";
while (i != e) {
A << *i;
i++;
if (i != e) {
A << ",";
}
}
return A << "}";
}
template<typename T, typename T2>
ostream &operator<<(ostream &A, const unordered_map<T, T2> &b) {
typename unordered_map<T, T2>::const_iterator i = b.begin(), e = b.end();
A << "{";
while (i != e) {
A << *i;
i++;
if (i != e) {
A << ",";
}
}
return A << "}";
}
template<typename T1, typename T2>
istream &operator>>(istream &A, const pair<T1, T2> &b) {
return A >> b.first >> b.second;
}
template<typename T>
void print_array(T b, T e, string s = " ") { // untested
while (b != e) {
cout << *b;
b++;
if (b != e) {
cout << s;
}
}
}
template<typename T>
void auto_print(T &b, size_t n, string s = " ") {
for (size_t i = 1; i < n; i++) {
cout << b[i] << s;
}
cout << b[n];
}
template<typename T>
void auto_print(T &b, string s = " ") { // untested
for (auto i : b) {
cout << i << s;
}
}
template<typename T>
void print_n(T b, size_t n, string s = " ") {
if (n == 0) return;
cout << *b;
for (size_t i = 1; i < n; i++) {
b++;
cout << s << *b;
}
}
template<typename T>
void read_array(T b, T e) {
while (b != e) {
cin >> *b;
b++;
}
}
template<typename T>
void auto_read(T &b, size_t n) {
for (size_t i = 1; i <= n; i++) {
cin >> b[i];
}
}
template<typename T>
void read_n(T b, size_t n) { // untested
cin >> *b;
for (size_t i = 1; i < n; i++) {
b++;
cin >> *b;
}
}
template <typename T>
string to_string(const T& value) {
ostringstream oss;
oss << value;
return oss.str();
}
template <typename Array>
string array_debug_impl(const Array& a) {
return "";
}
template <typename Array, typename First, typename... Rest>
string array_debug_impl(const Array& a, First first, Rest... rest) {
string current = "[" + to_string(first) + "]";
string next = array_debug_impl(a, rest...);
return current + next;
}
template <typename T>
decltype(auto) get_nested(T&& first) {
return forward<T>(first);
}
template <typename T, typename U, typename... Args>
decltype(auto) get_nested(T&& first, U&& second, Args&&... args) {
return get_nested(forward<T>(first)[forward<U>(second)], forward<Args>(args)...);
}
template <typename Array, typename... Args>
string array_debug(const Array& a, Args... args) {
string indices_str = array_debug_impl(a, args...);
ostringstream value_oss;
value_oss << get_nested(a, args...);
return indices_str + " = " + value_oss.str();
}
ostream &operator<<(ostream &a, ostream &b) {
return b;
}
#if 1 // use debug macros
#define aedebug(first, ...) #first << array_debug(first, __VA_ARGS__)
#define spc << " " <<
#endif
#undef quick_io_int_length_limit
#undef quick_io_int_radix_type
#undef quick_io_length_type
}
namespace MATH {
template<typename Ta, typename Tb, typename Tm>
Ta quickpower(Ta a, Tb b, Tm MOD) { // MOD \in P
if (b < 0) {
b = b % (MOD - 1) + MOD - 1;
}
a %= MOD;
Ta c = 1;
while (b) {
if (b & 1) {
c *= a;
c %= MOD;
}
a *= a;
a %= MOD;
b >>= 1;
}
return c;
}
template<typename T>
T gcd(T a, T b) {
if (b == T(0))
return a;
return gcd(b, a % b);
}
template<typename T>
T lcm(T a, T b) {
return a * b / gcd(a, b);
}
template<typename T, typename T1, typename T2>
T exgcd(T a, T b, T1 &x, T2 &y) {
if (b == 0) {
x = 1;
y = 0;
return a;
}
T ans = exgcd(b, a % b, x, y);
T1 X = y;
T2 Y = (T2)x - ((T2)a / (T2)b) * y;
x = X;
y = Y;
return ans;
}
template<typename T>
T log2_(T k) {
if (k == 0) return 0;
T ans = 0;
if (k >> 32) ans += 32, k >>= 32;
if (k >> 16) ans += 16, k >>= 16;
if (k >> 8) ans += 8, k >>= 8;
if (k >> 4) ans += 4, k >>= 4;
if (k >> 2) ans += 2, k >>= 2;
if (k >> 1) ans += 1;
return ans;
}
template<typename T, typename T2>
void build_power(T *power_array, T2 power_base, size_t len) {
power_array[0] = 1;
for (size_t i = 1; i <= len; i++) {
power_array[i] = power_array[i - 1] * (T)power_base;
}
}
template<typename T1, typename T2>
void build_factorial(int n, T1 *f, T2 *inv) {
f[0] = 1;
for (int i = 1; i <= n; i++) {
f[i] = f[i - 1] * (T1)i;
}
if (inv == nullptr) {
return;
}
inv[n] = T2(1) / T2(f[n]);
for (int i = n - 1; i >= 0; i--) {
inv[i] = inv[i + 1] * (T2)(i + 1);
}
}
template<typename T1, typename T2>
T1 C(size_t n, size_t m, T1 *f, T2 *i) {
if (m > n) return 0;
return f[n] * (T1)i[m] * (T1)i[n - m];
}
// #define C(n, m, f, i) f[n] * i[m] * i[n - m] // define mod C
template<typename T_fac, typename T_inv>
T_fac Lucas_C(size_t n, size_t m, size_t p, T_fac *fac, T_inv *inv) {
if (n < p && m < p) {
return ((m > n) ? T_fac(0) : fac[n] * inv[m] % p * inv[n - m] % p);
}
return ((m % p > n % p) ? T_fac(0) : fac[n % p] * inv[m % p] % p * inv[n % p - m % p] % p * Lucas_C(n / p, m / p, p, fac, inv) % p);
}
template<typename T_fac, typename T_inv>
T_fac Lucas(size_t n, size_t m, size_t p, T_fac *fac, T_inv *inv) { // p \in Primes
T_fac *new_fac = fac;
T_inv *new_inv = inv;
if (new_fac == nullptr) new_fac = new T_fac[p];
if (new_inv == nullptr) new_inv = new T_inv[p];
new_fac[0] = 1;
for (size_t i = 1; i < p; i++) {
new_fac[i] = new_fac[i - 1] * T_fac(i) % T_fac(p);
}
new_inv[p - 1] = quickpower(new_fac[p - 1], p - 2, p);
for (size_t i = p - 2; i <= p; i--) {
new_inv[i] = new_inv[i + 1] * T_inv(i + 1) % T_inv(p);
}
T_fac ans = Lucas_C(n, m, p, new_fac, new_inv);
if (new_fac != fac) delete[] new_fac;
if (new_inv != inv) delete[] new_inv;
return ans;
}
}
namespace modulo_int {
#define mint_int long long
void exgcd(mint_int& x, mint_int& y, mint_int n, mint_int m) {
if (m) {
exgcd(y, x, m, n % m);
y -= n / m * x;
} else {
x = 1;
y = 0;
}
}
mint_int mint_exgcd_a, mint_exgcd_b;
#define mint_mod mod
struct mint {
mint_int n;
mint() : n(0) {}
mint(const mint_int &_n) { n = (_n % mint_mod + mint_mod) % mint_mod; }
template<typename T> const mint operator+(const T &x) const { return n + mint(x).n; }
template<typename T> const mint operator-(const T &x) const { return n - mint(x).n; }
template<typename T> const mint operator*(const T &x) const { return n * mint(x).n; }
template<typename T> const mint operator%(const T &x) const { return n % mint(x).n; }
template<typename T> const mint operator|(const T &x) const { return n | mint(x).n; }
template<typename T> const mint operator&(const T &x) const { return n & mint(x).n; }
template<typename T> const mint operator^(const T &x) const { return n ^ mint(x).n; }
template<typename T> const mint operator/(const T &x) const {
exgcd(mint_exgcd_a, mint_exgcd_b, mint(x).n, mint_mod);
return n * mint_exgcd_a;
}
template<typename T> mint &operator+=(const T x) { return *this = *this + (mint)x; }
template<typename T> mint &operator-=(const T x) { return *this = *this - (mint)x; }
template<typename T> mint &operator*=(const T x) { return *this = *this * (mint)x; }
template<typename T> mint &operator/=(const T x) { return *this = *this / (mint)x; }
template<typename T> mint &operator%=(const T x) { return *this = *this % (mint)x; }
template<typename T> mint &operator|=(const T x) { return *this = *this | (mint)x; }
template<typename T> mint &operator&=(const T x) { return *this = *this & (mint)x; }
template<typename T> mint &operator^=(const T x) { return *this = *this ^ (mint)x; }
mint &operator++() { return *this = n + 1; }
mint &operator--() { return *this = n - 1; }
mint operator++(signed) {
n = ((n + 1 == mint_mod) ? 0 : (n + 1));
return n - 1;
}
mint operator--(signed) {
n = (n ? (n - 1) : (mint_mod - 1));
return n + 1;
}
template<typename T> bool operator<(const T &b) { return n < mint(b).n; }
template<typename T> bool operator<=(const T &b) { return n <= mint(b).n; }
template<typename T> bool operator>(const T &b) { return n > mint(b).n; }
template<typename T> bool operator>=(const T &b) { return n >= mint(b).n; }
template<typename T> bool operator==(const T &b) { return n == mint(b).n; }
template<typename T> bool operator!=(const T &b) { return n != mint(b).n; }
operator mint_int() const { return n; }
mint operator-() const { return -n; }
const mint &operator+() const { return *this; }
};
istream &operator>>(istream &A, mint &b) {
mint_int c;
A >> c;
b = c;
return A;
}
ostream &operator<<(ostream &A, const mint &b) {
return A << b.n;
}
#undef mint_mod
#undef mint_int
}
namespace graph_algorithm {
int inf_of_type(int a) { return 0x3f3f3f3f; }
long long inf_of_type(long long a) { return 0x3f3f3f3f3f3f3f3fll; }
#define graph_array(a, n, type) vector<type> a(n + 1)
#define graph_array_val(n, type) vector<type>(n + 1)
#define graph_array_non_zero_val(n, type, val) vector<type>(n + 1, val)
#define graph_array_two_pointer_val(type, a, b) vector<type>(a, b)
#define graph_array_t(type) vector<type>
#define graph_vis(type) set<T>
#define graph_index signed
graph_index get_first_ele(short &x) { return x; }
graph_index get_first_ele(unsigned short &x) { return x; }
graph_index get_first_ele(signed &x) { return x; }
graph_index get_first_ele(unsigned &x) { return x; }
graph_index get_first_ele(long long &x) { return x; }
graph_index get_first_ele(unsigned long long &x) { return x; }
graph_index get_first_ele(__int128 &x) { return x; }
template<typename T, typename T2>
graph_index get_first_ele(pair<T, T2> &x) {
return get_first_ele(x.first);
}
// directivity "d"/"u", weightiness "w"/"u"
template<typename T>
void read_graph_d(vector<T> *e, graph_index m) {
graph_index u;
T v;
while (m--) {
cin >> u >> v;
e[u].push_back(v);
}
}
template<typename T>
void read_graph_u_u(vector<T> *e, graph_index m) {
T u, v;
while (m--) {
cin >> u >> v;
e[u].push_back(v);
e[v].push_back(u);
}
}
template<typename T, typename T2>
void read_graph_u_w(vector<pair<T, T2> > *e, graph_index m) {
T u, v;
T2 w;
while (m--) {
cin >> u >> v >> w;
e[u].push_back({v, w});
e[v].push_back({u, w});
}
}
#undef graph_array
#undef graph_array_val
#undef graph_array_non_zero_val
#undef graph_array_two_pointer_val
#undef graph_array_t
#undef graph_vis
#undef graph_index
}
#define lowbit(x) ((x)&-(x))
template<typename T, typename BIT_index = size_t, typename container = vector<BIT_index> >
struct BIT {
container t;
BIT() {}
BIT(const BIT_index &n) : t(n, 0) {}
BIT(T *a, const size_t &n) : t(a, next(a, n)) {
for (BIT_index i = 1; i < n; i++) {
if (i + lowbit(i) < n) {
t[i + lowbit(i)] += t[i];
}
}
}
template<typename ite>
BIT(const ite &b, const ite &e) : t(b, e) {
BIT_index n = t.size();
for (BIT_index i = 1; i < n; i++) {
if (i + lowbit(i) < n) {
t[i + lowbit(i)] += t[i];
}
}
}
BIT(const BIT_index &n, const T &a) : t(n, a) {
for (BIT_index i = 1; i < n; i++) {
if (i + lowbit(i) < n) {
t[i + lowbit(i)] += t[i];
}
}
}
void clear(const BIT_index &len = 0) {
t = container(len, 0);
}
size_t size() {
return t.size();
}
void update(BIT_index x, const T k) {
if (x == 0) {
t[0] += k;
}
#ifndef BIT_limit
#define __BIT_hd_limit(x) (x < t.size())
#else
#define __BIT_hd_limit(x) (BIT_limit(x))
#endif
while (x != 0 && __BIT_hd_limit(x)) {
t[x] += k;
x += lowbit(x);
}
#undef __BIT_hd_limit
}
T query(BIT_index x) {
T ans = t[0];
while (x) {
ans += t[x];
x ^= lowbit(x);
}
return ans;
}
T query(const BIT_index l, const BIT_index r) {
return query(r) - (l ? query(l - 1) : T(0));
}
T operator[](const BIT_index b) {
return query(b, b);
}
void resize(const BIT_index n) {
BIT_index m = t.size();
if (n <= t.size()) {
t.erase(t.begin() + n, t.end());
return;
}
t.insert(t.end(), n - m, 0);
for (BIT_index i = 0; i < n; i++) {
if (i + lowbit(i) >= m && i + lowbit(i) < n) {
t[i + lowbit(i)] += t[i];
}
}
}
};
#undef lowbit
using namespace quick_io;
#define graph_index signed
namespace structure {
struct uedge { // untested
// undirected edge
graph_index dest;
operator graph_index() const { return dest; }
bool operator<(const uedge &b) const { return dest < b.dest; }
};
struct uedge_with_id {
// undirected edge with index
graph_index dest, id;
operator pair<graph_index, graph_index>() const { return {dest, id}; }
bool operator<(const uedge_with_id &b) const { return dest < b.dest; }
};
template<typename T = graph_index, typename container = vector<vector<T> > >
struct basic_al {
// Adjacency List, decltype(container.operator[]()) = vector<T>&
container data;
size_t sz;
struct iterator : public decltype(data[graph_index()])::iterator {};
struct const_iterator : public decltype(data[graph_index()])::const_iterator {};
basic_al() : sz(0) {
#ifndef __IGNORE__NO_PARAMETER_GENERATION_WARNING__
cerr << "no parameter generated Adjacency List" << endl;
#endif
}
basic_al(size_t node_size) : sz(0), data(node_size + 1) {}
virtual void add_edge(graph_index a, T b) { data[a].push_back(b); }
const size_t &size() const { return sz; }
bool empty() const { return sz == 0; }
auto &operator[](graph_index x) { return data[x]; }
const auto &operator[](graph_index x) const { return data[x]; }
};
template<typename T = graph_index, typename container = vector<vector<T> > >
struct al_graph : public basic_al<T, container> {
// Adjacency List Graph
using basic_al<T, container>::basic_al;
};
template<typename T = graph_index, typename container = vector<vector<T> > >
struct al_uugraph : public al_graph<T, container> { // untested
// Adjacency List Undirected Unwighted Graph
using al_graph<T, container>::al_graph;
void add_edge(graph_index u, graph_index v) override {
basic_al<T, container>::add_edge(u, v);
basic_al<T, container>::add_edge(v, u);
}
};
template<typename T, typename container = vector<vector<T> > >
struct al_ugraph : public al_graph<T, container> {
// Adjacency List Undirected Graph
using al_graph<T, container>::al_graph;
template<typename T2>
void add_edge(graph_index u, graph_index v, const T2 &w) {
basic_al<T, container>::add_edge(u, {v, w});
basic_al<T, container>::add_edge(v, {u, w});
}
};
template<typename T,
typename head_container = vector<graph_index>,
typename nxt_container = vector<graph_index>,
typename data_container = vector<T> >
struct basic_fs {
// front star
data_container data;
nxt_container nxt;
head_container head;
graph_index cnt;
basic_fs() : cnt(-1) {
#ifndef __IGNORE__NO_PARAMETER_GENERATION_WARNING__
cerr << "no parameter generated Front Star" << endl;
#endif
}
basic_fs(graph_index N)
: data(N),
nxt(N, -1),
head(N, -1),
cnt(-1) {}
basic_fs(graph_index N, graph_index M)
: data(M),
nxt(M, -1),
head(N, -1),
cnt(-1) {}
const graph_index &add(graph_index x, T new_data) {
nxt[++cnt] = head[x];
data[cnt] = new_data;
return head[x] = cnt;
}
};
template<typename T,
typename head_container = vector<graph_index>,
typename nxt_container = vector<graph_index>,
typename data_container = vector<T> >
struct fs_graph : basic_fs<T,
head_container,
nxt_container,
data_container> {
using basic_fs<T,
head_container,
nxt_container,
data_container>::basic_fs;
};
}
namespace flow {
template<typename Cap>
struct mf_edge {
graph_index dest;
Cap cap;
};
template<typename Cap,
typename head_container = vector<graph_index>,
typename nxt_container = vector<graph_index>,
typename data_container = vector<mf_edge<Cap> >,
typename mc_contianer = vector<bool>,
typename dis_container = vector<graph_index> >
#define mf_graph_base structure::fs_graph<mf_edge<Cap>, \
head_container, \
nxt_container, \
data_container>
struct mf_graph : public mf_graph_base {
// max flow / min cut, Dinic
using mf_graph_base::fs_graph;
using mf_graph_base::data;
using mf_graph_base::nxt;
using mf_graph_base::head;
mf_graph() : mf_graph_base() {
#ifndef __IGNORE__NO_PARAMETER_GENERATION_WARNING__
cerr << "no parameter generated Maximum Flow Graph" << endl;
#endif
}
mf_graph(graph_index N) : mf_graph_base(N, N << 1) {} // N nodes, N edges
mf_graph(graph_index N, graph_index M) : mf_graph_base(N, M << 1) {} // N nodes, M edges
void add_edge(graph_index a, graph_index b, Cap cap) {
mf_graph_base::add(a, {b, cap});
mf_graph_base::add(b, {a, Cap(0)});
}
dis_container dis;
graph_index sink;
head_container cur_head;
Cap dfs(graph_index id, Cap max_flow) {
if (id == sink) {
return max_flow;
}
Cap now_flow = 0;
for (graph_index i = cur_head[id]; ~i; i = nxt[i]) {
if (data[i].cap && dis[data[i].dest] == dis[id] + 1) {
Cap cur_flow = dfs(data[i].dest, min(max_flow - now_flow, data[i].cap));
data[i].cap -= cur_flow;
data[i ^ 1].cap += cur_flow;
now_flow += cur_flow;
if (now_flow >= max_flow) {
return max_flow;
}
}
cur_head[id] = i = min(cur_head[id], i);
}
return now_flow;
}
Cap max_flow(graph_index source, graph_index Sink) {
Cap ans = 0;
sink = Sink;
while (true) {
cur_head = head;
dis = dis_container(head.size(), -1);
dis[source] = 0;
queue<graph_index> q;
q.push(source);
while (!q.empty()) {
graph_index t = q.front();
q.pop();
for (int i = head[t]; ~i; i = nxt[i]) {
if (dis[data[i].dest] == -1 && data[i].cap) {
dis[data[i].dest] = dis[t] + 1;
q.push(data[i].dest);
}
}
}
if (~dis[Sink]) {
Cap now_flow = dfs(source, numeric_limits<Cap>().max());
if (now_flow) {
ans += now_flow;
} else {
break;
}
} else {
break;
}
}
return ans;
}
mc_contianer min_cut(graph_index source, graph_index Sink, bool rebuild_flow = true) {
if (rebuild_flow) {
max_flow(source, Sink);
}
mc_contianer mc(head.size(), false);
mc[source] = true;
queue<graph_index> q;
q.push(source);
while (!q.empty()) {
graph_index t = q.front();
q.pop();
for (graph_index i = head[t]; ~i; i = nxt[i]) {
if (data[i].cap && !mc[data[i].dest]) {
mc[data[i].dest] = true;
q.push(data[i].dest);
}
}
}
return mc;
}
ostream &print_graph(ostream &a = cout) {
for (graph_index t = 0; t < (graph_index)head.size(); t++) {
for (graph_index i = head[t]; ~i; i = nxt[i]) {
if (1 & ~i) {
a << t << " " << data[i].dest << " " << data[i | 1].cap << "/" << data[i].cap + data[i | 1].cap << endl;
}
}
}
return a;
}
};
#undef mf_graph_base
}
#define int long long
#define min(x,y) (((x)<(y))?(x):(y))
#define max(x,y) (((x)>(y))?(x):(y))
#define lowbit(x) ((x)&-(x))
#define abs(x) (((x)<(0))?(-(x)):(x))
#define swap(a,b) a^=b^=a^=b
#define INF 1e18
#define sos ostream
#define sis istream
#define soss ostringstream
#define siss istringstream
#define bin(a,b) bitset<a>(b)
#define getbit(a,b) (((a)>>(b))&1)
#if 1 // using using of types
using LL = long long;
using pii = pair<int, int>;
using i32 = int32_t;
using u32 = uint32_t;
using i64 = int64_t;
using u64 = uint64_t;
using i128 = __int128_t;
using u128 = __uint128_t;
using vi = vector<int>;
using vvi = vector<vi>;
using vpii = vector<pii>;
#endif
ostream &cans(cout);
// #define cout cerr
#define MAXM 100005
#define MAXN 1005
int n, m, b[MAXN], still_ok[MAXN], a[MAXN][MAXN], s[MAXN];
vector<int> t[MAXN][MAXN];
signed main() {
multiple_cases(T, C)
{
for (int i = 0; i < MAXN; i++)
{
b[i] = still_ok[i] = s[i] = 0;
}
for (int i = 0; i < MAXN; i++)
{
for (int j = 0; j < MAXN; j++)
{
t[i][j].clear();
}
}
memset(a, 0, sizeof(a));
cin >> n >> m;
flow::mf_graph<int> g(MAXM);
for (int i = 1; i <= m; i++)
{
cin >> b[i];
if (!b[i])
{
still_ok[i] = -1;
}
g.add_edge(0, i, b[i]);
}
g.max_flow(0, n + m + 1);
for (int i = 1; i <= n; i++)
{
g.add_edge(i + m, n + m + 1, 1);
for (int j = 1; j <= m; j++)
{
cin >> a[i][j];
t[i][a[i][j]].push_back(j);
}
}
for (int i = 1; i <= n; i++)
{
cin >> s[i];
}
// cerr << "-----------------" << endl;
for (int i = 1; i <= n; i++)
{
int tea = m + 1;
for (int j = 1; j <= m; j++)
{
bool flag = 0;
for (int k : t[i][j])
{
if (~g.dis[k])
{
flag = 1;
break;
}
}
if (flag)
{
tea = j;
break;
}
}
cout << tea << " ";
if (tea > m)
{
continue;
}
for (int j : t[i][tea])
{
g.add_edge(j, m + i, 1);
}
g.max_flow(0, n + m + 1);
// g.print_graph(cerr) << i << endl;
for (int j = 1; j <= m; j++)
{
if (~g.dis[j])
{
still_ok[j] = i;
}
}
}
cout << endl;
for (int i = 1; i <= m; i++)
{
still_ok[i]++;
}
for (int i = 1; i <= n; i++)
{
int ans = i;
for (int j = 1; j <= s[i]; j++)
{
for (int k : t[i][j])
{
ans = min(ans, i - still_ok[k]);
}
}
cout << max(ans, 0) << " ";
}
cout << endl;
}
return 0;
}