zoukankan      html  css  js  c++  java
  • [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 } 
    View Code
  • 相关阅读:
    2012航拍香港
    2012航拍香港
    论玩镜头的三种境界[转自无忌fruitbear]
    论玩镜头的三种境界[转自无忌fruitbear]
    认识镜头的MTF值
    认识镜头的MTF值
    宾得十大名镜
    宾得十大名镜
    两个输入通道怎么判断通道顺序
    增加新功能和未知的修改操作
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/13925575.html
Copyright © 2011-2022 走看看