• bzoj3218 a + b Problem


    Description

    Input

    Output 

    Sample Input

    10
    0 1 7 3 9 2
    7 4 0 9 10 5
    1 0 4 2 10 2
    7 9 1 5 7 2
    6 3 5 3 6 2
    6 6 4 1 8 1
    6 1 6 0 6 5
    2 2 5 0 9 3
    5 1 3 0 2 5
    5 6 7 1 1 2

    Sample Output

    55

    正解:最小割+主席树优化连边。

    考虑拆点。$S$向$i$连$w$边,$i$向$T$连$b$边,$i'$向$i$连$p$边。如果$j$能使$i$变成奇怪的方格,那么$j$向$i'$连$inf$的边。

    我们发现这样求出最小割就是答案,然而建图是$O(n^{2})$的,我们用主席树优化连边就行了。

    每次新建一个版本,历史版本的结点向当前点连边,同时当前的$i$向主席树中经过的每一个点连边。

    我们查询路径时,把整个区间抠出来,然后对应的线段树结点向$i$连边就行了。

      1 //It is made by wfj_2048~
      2 #include <algorithm>
      3 #include <iostream>
      4 #include <cstring>
      5 #include <cstdlib>
      6 #include <cstdio>
      7 #include <vector>
      8 #include <cmath>
      9 #include <queue>
     10 #include <stack>
     11 #include <map>
     12 #include <set>
     13 #define inf (1<<30)
     14 #define N (500010)
     15 #define il inline
     16 #define RG register
     17 #define ll long long
     18 
     19 using namespace std;
     20 
     21 struct edge{ int nt,to,flow,cap; }g[1000010];
     22 
     23 int head[N],cur[N],d[N],q[N],a[N],l[N],r[N],n,num=1;
     24 int ls[N],rs[N],rt[N],hsh[N],sz,S,T,tot,ans,goal;
     25 
     26 il int gi(){
     27     RG int x=0,q=1; RG char ch=getchar();
     28     while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
     29     if (ch=='-') q=-1,ch=getchar();
     30     while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
     31     return q*x;
     32 }
     33 
     34 il void insert(RG int from,RG int to,RG int cap){
     35     g[++num]=(edge){head[from],to,0,cap},head[from]=num; return;
     36 }
     37 
     38 il int bfs(RG int S,RG int T){
     39     memset(d,0,sizeof(d)),d[S]=1;
     40     RG int h=0,t=1; q[t]=S;
     41     while (h<t){
     42     RG int x=q[++h],v;
     43     for (RG int i=head[x];i;i=g[i].nt){
     44         v=g[i].to;
     45         if (!d[v] && g[i].cap>g[i].flow){
     46         d[v]=d[x]+1,q[++t]=v;
     47         if (v==T) return 1;
     48         }
     49     }
     50     }
     51     return d[T];
     52 }
     53 
     54 il int dfs(RG int x,RG int T,RG int a){
     55     if (!a || x==T) return a; RG int flow=0,f,v;
     56     for (RG int &i=cur[x];i;i=g[i].nt){
     57     v=g[i].to;
     58     if (d[v]==d[x]+1 && g[i].cap>g[i].flow){
     59         f=dfs(v,T,min(a,g[i].cap-g[i].flow));
     60         if (!f){ d[v]=0; continue; }
     61         g[i].flow+=f,g[i^1].flow-=f;
     62         flow+=f,a-=f; if (!a) return flow;
     63     }
     64     }
     65     return flow;
     66 }
     67 
     68 il int maxflow(RG int S,RG int T){
     69     RG int flow=0;
     70     while (bfs(S,T)){
     71     memcpy(cur,head,sizeof(head));
     72     flow+=dfs(S,T,inf);
     73     }
     74     return flow;
     75 }
     76 
     77 il void build(RG int x,RG int &y,RG int l,RG int r,RG int p){
     78     y=++sz,ls[y]=ls[x],rs[y]=rs[x];
     79     insert(x,y,inf),insert(y,x,0);
     80     insert(goal,y,inf),insert(y,goal,0);
     81     if (l==r) return; RG int mid=(l+r)>>1;
     82     p<=mid ? build(ls[x],ls[y],l,mid,p) : build(rs[x],rs[y],mid+1,r,p);
     83     return;
     84 }
     85 
     86 il void query(RG int x,RG int l,RG int r,RG int xl,RG int xr){
     87     if (xl<=l && r<=xr){ insert(x,goal,inf),insert(goal,x,0); return; }
     88     RG int mid=(l+r)>>1;
     89     if (xr<=mid) query(ls[x],l,mid,xl,xr);
     90     else if (xl>mid) query(rs[x],mid+1,r,xl,xr);
     91     else query(ls[x],l,mid,xl,mid),query(rs[x],mid+1,r,mid+1,xr);
     92     return;
     93 }
     94 
     95 int main(){
     96 #ifndef ONLINE_JUDGE
     97     freopen("a+b.in","r",stdin);
     98     freopen("a+b.out","w",stdout);
     99 #endif
    100     n=gi(),S=2*n+1,T=2*n+2,sz=T;
    101     for (RG int i=1,b,w,p;i<=n;++i){
    102     a[i]=gi(),b=gi(),w=gi(),ans+=b+w;
    103     l[i]=gi(),r[i]=gi(),p=gi();
    104     insert(S,i,w),insert(i,S,0);
    105     insert(i,T,b),insert(T,i,0);
    106     insert(n+i,i,p),insert(i,n+i,0);
    107     hsh[++tot]=a[i],hsh[++tot]=l[i],hsh[++tot]=r[i];
    108     }
    109     sort(hsh+1,hsh+tot+1),tot=unique(hsh+1,hsh+tot+1)-hsh-1;
    110     for (RG int i=1;i<=n;++i){
    111     a[i]=lower_bound(hsh+1,hsh+tot+1,a[i])-hsh;
    112     l[i]=lower_bound(hsh+1,hsh+tot+1,l[i])-hsh;
    113     r[i]=lower_bound(hsh+1,hsh+tot+1,r[i])-hsh;
    114     goal=n+i,query(rt[i-1],1,tot,l[i],r[i]);
    115     goal=i,build(rt[i-1],rt[i],1,tot,a[i]);
    116     }
    117     printf("%d
    ",ans-maxflow(S,T));
    118     return 0;
    119 }
  • 相关阅读:
    测试阅读量
    JS中的 length, var i = [1,2]; i[length], 与 i.length, i["length"]的区别
    微信小程序:button组件的边框
    mongo学习笔记
    C言语语法总结(随时更新)
    Vim 常用命令总结
    php 文件操作
    git常用命令
    递归方式转迭代方式
    ECMAScript6 ES6 ES2015新语法总结
  • 原文地址:https://www.cnblogs.com/wfj2048/p/7228811.html
Copyright © 2020-2023  润新知