代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
using namespace std;
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
const int MAXN=205;
const int MAXM=2405;
int C,n,m,s,t,lim[MAXN],a[MAXN][MAXN],b[MAXN][MAXN][12],exp[MAXN];
int dep[MAXN*2],ans[MAXN],head[MAXN*2],hish[MAXN][MAXN*2],ecnt=-1,hisecnt[MAXN];
struct Edge{
int frm,to,nxt,cap;
}e[MAXM],hise[MAXN][MAXM*2];
inline void add_edge(int bg,int ed,int ca){
ecnt++;
e[ecnt].frm=bg;
e[ecnt].to=ed;
e[ecnt].nxt=head[bg];
e[ecnt].cap=ca;
head[bg]=ecnt;
swap(bg,ed);
ecnt++;
e[ecnt].frm=bg;
e[ecnt].to=ed;
e[ecnt].nxt=head[bg];
e[ecnt].cap=0;
head[bg]=ecnt;
}
inline void delete_edge(int stp){
while(ecnt>stp){
head[e[ecnt].frm]=e[ecnt].nxt;
ecnt--;
}
}
bool bfs(){
memset(dep,0x3f,sizeof dep);
queue<int> q;
while(!q.empty()) q.pop();
q.push(s);
dep[s]=1;
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=head[u];i!=-1;i=e[i].nxt){
int ver=e[i].to;
if(dep[ver]>1e9&&e[i].cap){
dep[ver]=dep[u]+1;
q.push(ver);
}
}
}
return dep[t]<1e9;
}
int dfs(int x,int pref){
if(!pref||x==t) return pref;
int flow=0,temp;
for(int i=head[x];i!=-1;i=e[i].nxt){
int ver=e[i].to;
if(dep[ver]==dep[x]+1&&(temp=dfs(ver,min(pref,e[i].cap)))){
flow+=temp;
pref-=temp;
e[i].cap-=temp;
e[i^1].cap+=temp;
if(!pref) break;
}
}
return flow;
}
bool check(int x,int y){
memcpy(head,hish[y-1],sizeof head);
memcpy(e,hise[y-1],sizeof e);
ecnt=hisecnt[y-1];
add_edge(s,x,1);
for(int i=1;i<=exp[x];i++){
int prev=ecnt;
for(int j=1;j<=b[x][i][0];j++)
add_edge(x,b[x][i][j],1);
if(bfs()&&dfs(s,1e9)) return 1;
for(int j=1;j<=b[x][i][0];j++)
delete_edge(prev);
}
return 0;
}
int solve(int x){
int l=1,r=x-1,rez=0;
while(l<=r){
int mid=((l+r)>>1);
if(check(x,mid)) l=mid+1,rez=mid;
else r=mid-1;
}
return x-rez;
}
int main(){
int T=read();C=read();
while(T--){
memset(b,0,sizeof b);
memset(ans,0,sizeof ans);
memset(head,-1,sizeof head);
ecnt=-1;
n=read(),m=read();
s=n+m+1,t=s+1;
for(int i=1;i<=m;i++){
lim[i]=read();
add_edge(n+i,t,lim[i]);
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
a[i][j]=read();
if(a[i][j])
b[i][a[i][j]][++b[i][a[i][j]][0]]=n+j;
}
for(int i=1;i<=n;i++)
exp[i]=read();
memcpy(hish[0],head,sizeof head);
memcpy(hise[0],e,sizeof e);
hisecnt[0]=ecnt;
for(int i=1;i<=n;i++){
add_edge(s,i,1);
int prev=ecnt;
for(int j=1;j<=m;j++){
for(int k=1;k<=b[i][j][0];k++)
add_edge(i,b[i][j][k],1);
if(bfs()&&dfs(s,1e9)){
ans[i]=j;
break;
}
for(int k=1;k<=b[i][j][0];k++)
delete_edge(prev);
}
memcpy(hish[i],head,sizeof head);
memcpy(hise[i],e,sizeof e);
hisecnt[i]=ecnt;
}
for(int i=1;i<=n;i++)
printf("%d ",(ans[i]==0?m+1:ans[i]));
printf("\n");
for(int i=1;i<=n;i++){
if(ans[i]&&ans[i]<=exp[i]){
printf("0 ");
continue;
}
printf("%d ",solve(i));
}
printf("\n");
}
return 0;
}