题意:
解法:
首先,如果sum{a[i]}!=sum{b[i]},那么一定无解,这里先特判一下.
容易看出网络流可以判断是否有解.
设源点S,汇点T,
将点i上的人不动,看作是存在一条(i,i)的边.
将每个点拆为出点和入点,令id1[i]表示点i的出点,id2[i]表示点i的入点.
建图:
(S->id1[i],a[i]),即每个点有a[i]个人.
(id2[i]->T,b[i]),即每个点需要b[i]个人.
(id1[i]->id2[i],inf),即点i的人可以留在原地.
如果存在边(a,b),那么(id1[a]->id2[b],inf),(id1[b]->id2[a],inf),即a和b的人可以互相走.
跑dinic求最大流,如果maxflow!=sum{B[i]},那么无解,否则有解.
这题还需要输出一组方案,
我们到残余网络上的回边中找流的大小即可,回边的流量就是走这条边的人数.
code:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxm=2e6+5;
int head[maxm],nt[maxm<<2],to[maxm<<2],w[maxm<<2],cnt=1;
int d[maxm],S,T,maxflow;
int a[111],b[111];
int ans[111][111];
int id1[111],id2[111],rev[maxm],idx;
int n,m;
void add(int x,int y,int z){
cnt++;nt[cnt]=head[x];head[x]=cnt;to[cnt]=y;w[cnt]=z;
}
void add2(int x,int y,int z){
add(x,y,z);add(y,x,0);
}
bool bfs(){
for(int i=1;i<=idx;i++)d[i]=0;
queue<int>q;
q.push(S);
d[S]=1;
while(q.size()){
int x=q.front();q.pop();
for(int i=head[x];i;i=nt[i]){
int v=to[i];
if(!d[v]&&w[i]){
d[v]=d[x]+1;
q.push(v);
if(v==T)return 1;
}
}
}
return 0;
}
int dfs(int x,int flow){
if(x==T)return flow;
int res=flow;
for(int i=head[x];i;i=nt[i]){
int v=to[i];
if(w[i]&&d[v]==d[x]+1){
int k=dfs(v,min(res,w[i]));
w[i]-=k;
w[i^1]+=k;
res-=k;
if(!k)d[v]=-1;
if(!res)break;
}
}
return flow-res;
}
void dinic(){
maxflow=0;
while(bfs()){
maxflow+=dfs(S,1e9);
}
}
void solve(){
cin>>n>>m;
int sumA=0,sumB=0;
for(int i=1;i<=n;i++)cin>>a[i],sumA+=a[i];
for(int i=1;i<=n;i++)cin>>b[i],sumB+=b[i];
if(sumA!=sumB){
cout<<"NO"<<endl;return ;
}
for(int i=1;i<=n;i++){
id1[i]=++idx;rev[idx]=i;
id2[i]=++idx;rev[idx]=i;
}
S=++idx;T=++idx;
for(int i=1;i<=n;i++){
add2(S,id1[i],a[i]);
add2(id2[i],T,b[i]);
}
for(int i=1;i<=n;i++){
add2(id1[i],id2[i],1e9);
}
for(int i=1;i<=m;i++){
int x,y;cin>>x>>y;
add2(id1[x],id2[y],1e9);
add2(id1[y],id2[x],1e9);
}
dinic();
if(maxflow!=sumB){
cout<<"NO"<<endl;return ;
}
cout<<"YES"<<endl;
for(int k=1;k<=n;k++){
int x=id1[k];
for(int i=head[x];i;i=nt[i]){
if(i&1)continue;
int v=to[i];
if(v==S||v==T)continue;
v=rev[v];
ans[k][v]+=w[i^1];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cout<<ans[i][j]<<' ';
}
cout<<endl;
}
}
signed main(){
ios::sync_with_stdio(0);cin.tie(0);
solve();
return 0;
}