P3973 [TJOI2015]线性代数 题解
之前居然不知道矩阵的转置是什么/qd,百度一下发现这就是把矩阵的横竖颠倒一下。
然后进行一个柿子的推,发现
令
跑 Dinic 即可,答案即
#include<bits/stdc++.h>
#define ll long long
#define rep(i,s,e) for(int i=(s);i<=(e);++i)
#define Rep(i,s,e) for(int i=(e);i>=(s);--i)
using namespace std;
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=1010,M=1e6+5;
int n,s,t,b[N>>1][N>>1],c[N],sum[N];
int head[N],rad[N],cnt=1;
struct qwq{
int v,w,nxt;
}e[M];
inline void add(int u,int v,int w){
e[++cnt]={v,w,head[u]},head[u]=cnt;
e[++cnt]={u,0,head[v]},head[v]=cnt;
}
int dep[N];
inline bool bfs(){
queue<int> q;
rep(i,1,t) dep[i]=0;
dep[s]=1,q.push(s);
while(!q.empty()){
int x=q.front();q.pop();
rad[x]=head[x];
for(int i=head[x];i;i=e[i].nxt){
int v=e[i].v,w=e[i].w;
if(w&&!dep[v]) dep[v]=dep[x]+1,q.push(v);
}
}
return dep[t]!=0;
}
int dfs(int x,int flow){
if(x==t) return flow;
int out=0;
for(int &i=rad[x];i;i=e[i].nxt){
int v=e[i].v,&w=e[i].w;
if(w&&dep[v]==dep[x]+1){
int res=dfs(v,min(flow,w));
out+=res,flow-=res,w-=res,e[i^1].w+=res;
}
if(!flow) break;
}
if(flow) dep[x]=-1;
return out;
}
signed main(){
n=read(),s=n<<1|1,t=s+1;
int ans=0,tmp;
rep(i,1,n) rep(j,1,n) b[i][j]=read(),sum[j]+=b[i][j];
rep(i,1,n) c[i]=read(),ans+=sum[i];
rep(i,1,n){
add(s,i,sum[i]),add(i+n,t,c[i]),add(i,i+n,1e9);
rep(j,1,n) if(j!=i) add(i,j+n,b[j][i]);
}
while(bfs()) while(tmp=dfs(s,1e9)) ans-=tmp;
// rep(i,1,t) cerr<<dep[i]<<' ';cerr<<endl;
printf("%d\n",ans);
}