#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; typedef long long ll; typedef vector vi; typedef pair pii; #define MP make_pair #define PB push_back #define inf 1000000007 #define rep(i,n) for(int i = 0; i < (int)(n); ++i) #define all(x) (x).begin(),(x).end() template void Fill(A (&array)[N], const T &val){ std::fill( (T*)array, (T*)(array+N), val ); } template inline bool chmax(T &a, T b){ if(a inline bool chmin(T &a, T b){ if(a>b){ a = b; return true; } return false; } template class Dinic { private: int V; vector level,iter; void bfs(int s) { fill(level.begin(),level.end(),-1); queue que; level[s] = 0; que.push(s); while(!que.empty()){ int v = que.front(); que.pop(); for(auto& e : G[v]){ if(e.cap > 0 && level[e.to] < 0){ level[e.to] = level[v] + 1; que.push(e.to); } } } } T dfs(int v,int t,T f) { if(v==t){ return f; } for(int& i = iter[v]; i < (int)G[v].size(); i++){ edge& e = G[v][i]; if(e.cap > 0 && level[v] < level[e.to]){ T d = dfs(e.to,t,min(f,e.cap)); if(d > 0){ e.cap -= d; G[e.to][e.rev].cap += d; return d; } } } return 0; } public: struct edge{ int to; T cap; int rev; }; vector > G; Dinic(int node_size) : V(node_size), level(V), iter(V), G(V){} //辺を張る void add_edge(int from,int to,T cap) { G[from].push_back((edge){to,cap,(int)G[to].size()}); G[to].push_back((edge){from,(T)0,(int)G[from].size()-1}); } //最大流を計算 T solve(int s,int t) { T flow = 0; for(;;){ bfs(s); if(level[t] < 0) return flow; fill(iter.begin(),iter.end(),0); T f; while((f=dfs(s,t,numeric_limits::max())) > 0){ flow += f; } } } }; int main(){ int n,k; cin >> n >> k; vector a(n); rep(i,n) cin >> a[i]; vector b(n); rep(i,n) cin >> b[i]; vector > p(n,vector(n)); priority_queue > > pq; rep(i,n){ rep(j,n){ cin >> p[i][j]; pq.push(MP(p[i][j],MP(i,j))); } } vector > res(n,vector(n)); while(!pq.empty()){ auto x = pq.top(); pq.pop(); vector > zz; int iii = x.second.first; int jjj = x.second.second; if(a[iii]>0&&b[jjj]>0){ zz.push_back(MP(iii,jjj)); while(!pq.empty()){ auto xx = pq.top(); int ii = xx.second.first; int jj = xx.second.second; if(xx.first == x.first){ pq.pop(); if(a[ii]>0&&b[jj]>0){ zz.push_back(MP(ii,jj)); } }else{ break; } } Dinic dc(2*n+2); int S = 2*n; int T = 2*n+1; rep(i,n){ if(a[i]!=0){ dc.add_edge(S,i,a[i]); } if(b[i]!=0){ dc.add_edge(i+n,T,b[i]); } } // cerr << "test" << endl; for(auto xx:zz){ // cerr << xx.first << " " << xx.second << endl; dc.add_edge(xx.first,xx.second + n,1); } dc.solve(S,T); auto &g = dc.G; rep(i,n){ for(auto xx:g[i]){ // cerr << i << " " <