为 的01矩阵.
我们先把所有 选择,再考虑 的影响.
由于以后不管怎样代价都会减少,所有我们要的操作就是最小化变化,由 可以猜测用最小割.
考虑两个点 ,我们令最后 侧的点表示0,否则为1.然后建出这样的图:
则有:
解得:
特别的,推广到多点的时候对于 .
然后跑最小割就求出了最小损失.
#include<bits/stdc++.h>
#define lc (x<<1)
#define rc (x<<1|1)
#define gc getchar()//(p1==p2&&(p2=(p1=buf)+fread(buf,1,size,stdin),p1==p2)?EOF:*p1++)
#define mk make_pair
#define pi pair<int,int>
#define pb push_back
#define IT iterator
#define fi first
#define se second
#define vi vector<int>
#define SZ(a) ((int)a.size())
#define all(a) a.begin(),a.end()
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int N=510,M=N*N,size=1<<20,mod=998244353;
//char buf[size],*p1=buf,*p2=buf;
template<class o> void qr(o &x) {
char c=gc; x=0; int f=1;
while(!isdigit(c)){if(c=='-')f=-1; c=gc;}
while(isdigit(c)) x=x*10+c-'0',c=gc;
x*=f;
}
template<class o> void qw(o x) {
if(x/10) qw(x/10);
putchar(x%10+'0');
}
template<class o> void pr1(o x) {
if(x<0)x=-x,putchar('-');
qw(x); putchar(' ');
}
template<class o> void pr2(o x) {
if(x<0)x=-x,putchar('-');
qw(x); puts("");
}
int n,s[N],b[N][N],ans,st,ed,d[N],q[N],l,r;
struct edge{int y,next,c;}a[M]; int len=1,last[N],cur[N];
void ins(int x,int y,int c) {a[++len]=(edge){y,last[x],c}; last[x]=len;}
void add(int x,int y,int c,int d) {ins(x,y,c); ins(y,x,d);}
bool bfs() {
q[l=r=1]=st; memset(d+1,0,sizeof(int[ed])); d[st]=1;
while(l<=r) {
int x=q[l++];
for(int k=last[x],y;k;k=a[k].next)
if(!d[y=a[k].y]&&a[k].c)
{q[++r]=y; d[y]=d[x]+1;}
}
return d[ed];
}
int dfs(int x,int f) {
if(x==ed) return f;
int s=0,t;
for(int &k=cur[x],y,z;k;k=a[k].next) {
y=a[k].y; z=min(a[k].c,f-s);
if(d[y]==d[x]+1&&z) {
s+=t=dfs(y,z);
a[k].c-=t; a[k^1].c+=t;
if(s==f) return f;
}
}
if(!s) d[x]=0;
return s;
}
int main() {
qr(n); st=0; ed=n+1;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
qr(b[i][j]),ans+=b[i][j],s[i]+=b[i][j],s[j]+=b[i][j];
for(int i=1,x;i<=n;i++) qr(x),add(i,ed,x*2,0);
for(int i=1;i<=n;i++) {
add(st,i,s[i],0);
for(int j=i+1;j<=n;j++)
add(i,j,b[i][j]+b[j][i],b[i][j]+b[j][i]);
}
int cnt=0;
while(bfs())
memcpy(cur,last,sizeof(int[ed+1])),cnt+=dfs(st,mod);
pr2(ans-cnt/2);
return 0;
}
nt=0;
while(bfs())
memcpy(cur,last,sizeof(int[ed+1])),cnt+=dfs(st,mod);
pr2(ans-cnt/2);
return 0;
}