[atARC107F]Sum of Abs
价值即等价于给每一个点系数$p_{i}=\pm 1$,使得$\forall (x,y)\in E,p_{x}=p_{y}$的最大的$\sum_{i=1}^{n}p_{i}b_{i}$
如果没有删除(当然可以直接求绝对值),考虑网络流建图:将$b_{i}$分为正负两类,$S$向正的连$2b_{i}$的边,负的向$T$连$-2b_{i}$的边,将图中直接相连的两点连上流量为$\infty$的边,那么若两点不同向,则必须有一个被割掉
考虑删除,可以看作这个这个点不要求正负,同时其也不会帮助连边,因此将一个点拆开,并建$(i,i+n)$一条$a_{i}+|b_{i}|$的边表示删去这个点所付出的代价
同时对于一条边,连$(x+n,y)$和$(y+n,x)$,此时若$(x,x+n)$被删掉,则无法通过$x$走到$y+n$,即实现不帮助连边
最终答案即$\sum_{i=1}^{n}|b_{i}|-最小割$,时间复杂度为$o(n^{3})$
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 605 4 #define oo 0x3f3f3f3f 5 struct ji{ 6 int nex,to,len; 7 }edge[N<<2]; 8 queue<int>q; 9 int E,n,m,x,y,ans,head[N],a[N],work[N],d[N]; 10 void add(int x,int y,int z){ 11 edge[E].nex=head[x]; 12 edge[E].to=y; 13 edge[E].len=z; 14 head[x]=E++; 15 if (E&1)add(y,x,0); 16 } 17 bool bfs(){ 18 memset(d,oo,sizeof(d)); 19 q.push(0); 20 d[0]=0; 21 while (!q.empty()){ 22 int k=q.front(); 23 q.pop(); 24 for(int i=head[k];i!=-1;i=edge[i].nex) 25 if ((edge[i].len)&&(d[edge[i].to]==oo)){ 26 d[edge[i].to]=d[k]+1; 27 q.push(edge[i].to); 28 } 29 } 30 return d[2*n+1]!=oo; 31 } 32 int dfs(int k,int s){ 33 if (k>2*n)return s; 34 for(int &i=work[k];i!=-1;i=edge[i].nex) 35 if ((edge[i].len)&&(d[edge[i].to]==d[k]+1)){ 36 int p=dfs(edge[i].to,min(s,edge[i].len)); 37 if (p){ 38 edge[i].len-=p; 39 edge[i^1].len+=p; 40 return p; 41 } 42 } 43 return 0; 44 } 45 int dinic(){ 46 int k,ans=0; 47 while (bfs()){ 48 memcpy(work,head,sizeof(head)); 49 while (k=dfs(0,oo))ans+=k; 50 } 51 return ans; 52 } 53 int main(){ 54 scanf("%d%d",&n,&m); 55 for(int i=1;i<=n;i++)scanf("%d",&a[i]); 56 memset(head,-1,sizeof(head)); 57 for(int i=1;i<=n;i++){ 58 scanf("%d",&x); 59 ans+=abs(x); 60 add(i,i+n,abs(x)+a[i]); 61 if (x>=0)add(0,i,2*x); 62 else add(i+n,2*n+1,-2*x); 63 } 64 for(int i=1;i<=m;i++){ 65 scanf("%d%d",&x,&y); 66 add(x+n,y,oo); 67 add(y+n,x,oo); 68 } 69 printf("%d",ans-dinic()); 70 }