解析
熟练和固化在有些时候是等价的。
一个看起来喜闻乐见的模型。
n
2
n^2
n2 信息量你在逗我…
结果是:点数
n
2
n^2
n2 TLE,边数
n
2
n^2
n2 AC。
一种之前所没有见过的打开方式。
还是考虑最小割模型,点
i
i
i 向原点连一条
A
i
A_i
Ai 的边,断则表示雇佣。
不同的是,不再对每一对
(
i
,
j
)
(i,j)
(i,j) 开虚点,而是直接从
i
i
i 向汇点连一条
∑
E
i
,
j
\sum E_{i,j}
∑Ei,j 的边,表示
i
i
i 获得了所有的加成收益。
然后我们需要补偿,如果
j
j
j 没有雇佣,那么
i
i
i 不仅无法获得收益,还会付出代价,两相做差,应该连一条
(
j
,
i
,
2
E
i
,
j
)
(j,i,2E_{i,j})
(j,i,2Ei,j) 的边。
即可。
思维打开!
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define ok debug("OK\n")
using namespace std;
const int N=5e6+100;
const ll inf=2e12;
inline ll read(){
ll x(0),f(1);char c=getchar();
while(!isdigit(c)) {if(c=='-')f=-1;c=getchar();}
while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}
return x*f;
}
int n,m,id;
int s,t,tot;
struct node{
int to,nxt;
ll cap;
}p[N<<1];
int fi[N],cur[N],cnt;
inline void Addline(int x,int y,ll cap){
p[++cnt]=(node){y,fi[x],cap};fi[x]=cnt;
}
inline void add(int x,int y,ll c){
Addline(x,y,c);Addline(y,x,0);
}
int bel[N];
int q[N],st,ed;
int bfs(){
memset(bel,0,sizeof(int)*(tot+1));
bel[s]=1;
q[st=ed=1]=s;
while(st<=ed){
int now=q[st++];
for(int i=cur[now]=fi[now];~i;i=p[i].nxt){
int to=p[i].to;
if(!p[i].cap||bel[to]) continue;
bel[to]=bel[now]+1;
q[++ed]=to;
}
}
return bel[t];
}
ll dfs(int x,ll lim){
if(x==t||!lim) return lim;
ll res(0);
for(int &i=cur[x];~i;i=p[i].nxt){
int to=p[i].to;
if(bel[to]!=bel[x]+1) continue;
ll add=dfs(to,min(lim,p[i].cap));
res+=add;lim-=add;
p[i].cap-=add;p[i^1].cap+=add;
if(!lim) break;
}
if(!res) bel[x]=-1;
return res;
}
ll dinic(){
ll flow(0),tmp(0);
while(bfs()){
while((tmp=dfs(s,inf))) flow+=tmp;
}
return flow;
}
ll w[N];
signed main(){
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
memset(fi,-1,sizeof(fi));cnt=-1;
tot=n=read();
s=++tot;t=++tot;
ll ans(0);
for(int i=1;i<=n;i++){
int x=read();
add(s,i,x);
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
ll x=read();
ans+=x;
add(i,j,x*2);
w[i]+=x;
}
}
for(int i=1;i<=n;i++) add(i,t,w[i]);
printf("%lld\n",ans-dinic());
return 0;
}