这个建图不难想吧 然后就是找到一个负环 增广一通就好了
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<cstring>
#define cl(x) memset(x,0,sizeof(x))
using namespace std;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}
inline bool read(int &x){
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; else if (c==EOF) return 0;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b; return 1;
}
const int N=205;
struct edge{
int u,v,w,next;
}G[N*N];
int head[N],inum=1;
inline void add(int u,int v,int w,int p){
G[p].u=u; G[p].v=v; G[p].w=w; G[p].next=head[u]; head[u]=p;
}
int vst[N];
int ins[N],dis[N],pre[N];
int cnt[N];
int l,r,Q[100005];
int S,T;
#define V G[p].v
inline int SPFA(int s){
l=r=-1;
for (int i=1;i<=T;i++) dis[i]=1<<30,pre[i]=0,ins[i]=0,cnt[i]=0;
Q[++r]=s; ins[s]=1; dis[s]=0; cnt[s]++;
while (l<r){
int u=Q[++l]; ins[u]=0;
for (int p=head[u];p;p=G[p].next)
if (dis[V]>dis[u]+G[p].w){
dis[V]=dis[u]+G[p].w; pre[V]=u;
if (!ins[V]){
Q[++r]=V; ins[V]=1;
if ((++cnt[V])>T)
return V;
}
}
}
return -1;
}
int n,m;
int tot[N],Map[N][N];
int xs[N],ys[N],ws[N];
inline int Dis(int i,int j){
return abs(xs[i]-xs[j])+abs(ys[i]-ys[j]);
}
int main(){
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
while (read(n) && read(m)){
S=n+m+2; T=n+m+1;
for (int i=1;i<=n+m;i++)
read(xs[i]),read(ys[i]),read(ws[i]);
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++){
read(Map[i][j]);
tot[j]+=Map[i][j];
add(i,n+j,Dis(i,n+j),++inum);
if (Map[i][j]) add(n+j,i,-Dis(i,n+j),++inum);
}
for (int j=1;j<=m;j++)
if (tot[j]){
add(T,n+j,0,++inum);
if (tot[j]<ws[n+j]) add(n+j,T,0,++inum);
}
int u=-1;
for (int i=1;i<=T && u==-1;i++)
u=SPFA(i);
if (u==-1)
printf("OPTIMAL\n");
else{
printf("SUBOPTIMAL\n");
cl(vst);
int v=u,now;
while(vst[pre[v]]==0){
vst[v]=1;
v=pre[v];
}
now=v;
do{
if(pre[now]<=n && now>n) Map[pre[now]][now-n]++;
if(pre[now]>n && now<=n) Map[now][pre[now]-n]--;
now=pre[now];
}while(now!=v);
for(int i=1;i<=n;i++,printf("\n"))
for(int j=1;j<=m;j++)
printf("%d ",Map[i][j]);
}
cl(tot); cl(head); inum=1; cl(vst);
}
}