把那个式子化简一下(这个矩阵不能用交换律2333)出来的大概就是∑∑ai*aj*bij-∑ai*ci貌似这就可以最小割了
从起点向不bij连边,流量bij,bij向ci,cj连边,流量inf,然后c[]向汇点连边,流量c[].
(连边写的太丑,勿喷233)
1 #include<bits/stdc++.h> 2 #define inf 0x7fffffff 3 #define LL long long 4 #define N 200005 5 using namespace std; 6 inline int ra() 7 { 8 int x=0,f=1; char ch=getchar(); 9 while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();} 10 while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} 11 return x*f; 12 } 13 int S,T; 14 struct nodE{ 15 int to,next,v; 16 }e[N<<3]; 17 int n,head[N<<1],cnt=1,h[N<<1]; 18 int q[N<<2],ans; 19 void insert(int x, int y, int v) 20 { 21 e[++cnt].to=y; 22 e[cnt].next=head[x]; 23 e[cnt].v=v; 24 head[x]=cnt; 25 } 26 bool bfs() 27 { 28 int l=0,r=1; q[0]=S; 29 for (int i=0; i<=T; i++) h[i]=0; h[S]=1; 30 while (l<r) 31 { 32 int x=q[l++]; 33 for (int i=head[x];i;i=e[i].next) 34 if (e[i].v && h[e[i].to]==0) 35 { 36 h[e[i].to]=h[x]+1; 37 q[r++]=e[i].to; 38 } 39 } 40 return h[T]; 41 } 42 int dfs(int x, int f) 43 { 44 if (x==T) return f; 45 int w,ww=0; 46 for (int i=head[x];i;i=e[i].next) 47 if (h[e[i].to]==h[x]+1 && e[i].v) 48 { 49 w=dfs(e[i].to,min(e[i].v,f-ww)); 50 e[i].v-=w; e[i^1].v+=w; ww+=w; 51 if (ww==f) return f; 52 } 53 if (!ww) h[x]=0; 54 return ww; 55 } 56 void dinic() 57 { 58 while (bfs()) ans-=dfs(S,inf); 59 } 60 int main() 61 { 62 n=ra(); S=0,T=n*n+n+2; 63 for (int i=1; i<=n; i++) 64 for (int j=1; j<=n; j++) 65 { 66 int x=ra(); 67 ans+=x; 68 insert(S,(i-1)*n+j,x); 69 insert((i-1)*n+j,S,0); 70 insert((i-1)*n+j,n*n+i,inf); 71 insert(n*n+i,(i-1)*n+j,0); 72 insert((i-1)*n+j,n*n+j,inf); 73 insert(n*n+j,(i-1)*n+j,0); 74 } 75 for (int i=1; i<=n; i++) 76 { 77 int x=ra(); 78 insert(n*n+i,T,x); 79 insert(T,n*n+i,0); 80 } 81 dinic(); 82 cout<<ans; 83 return 0; 84 }