zoukankan      html  css  js  c++  java
  • BZOJ3218 A+B problem

    题目传送门

    分析:

    首先把公式换一下。。。

    ans=sigma(i<=n){w[i]+b[i]} - sigma(i为白色){b[i]} -sigma(i为黑色){w[i]} - sigma(i奇怪){p[i]}

    然后我们就需要后面那一块最小。。。

    非黑即白是一对矛盾关系,奇怪的点也是一个矛盾关系

    于是考虑最小割

    首先每个点分别向S和T连边,容量分别是b[i]与w[i]

    然后每个点 i 复制出一个 i' 连容量为p[i]的边

    i' 再向所有矛盾的 j 连边,容量INF

    demo,边数好像会炸

    然后发现非法的 j 是区间

    然后就线段树连边

    编号还要比 i 小。。。

    那就只有主席树了

    这么强行地把主席树和网络流联系起来吗,无力吐槽2333

    8是很懂,这个范围能过。。。

      1 #include<cstdio>
      2 #include<cmath>
      3 #include<queue>
      4 #include<vector>
      5 #include<algorithm>
      6 #include<iostream>
      7 #include<cstring>
      8   
      9 #define maxn 5005
     10 #define maxm 1000005
     11 #define INF 0x3f3f3f3f
     12 #define opst(i) (((i-1)^1)+1)
     13  
     14 using namespace std;
     15   
     16 inline int getint()
     17 {
     18     int num=0,flag=1;char c;
     19     while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
     20     while(c>='0'&&c<='9')num=num*10+c-48,c=getchar();
     21     return num*flag;
     22 }
     23  
     24 int n,S,T,N;
     25 int fir[maxn*20],nxt[maxm],to[maxm],cap[maxm],cnt;
     26 int h[20*maxn];
     27 int A[maxn],L[maxn],R[maxn],B[maxn],W[maxn],P[maxn],Q[3*maxn];
     28 struct node{int lc,rc;}t[maxn*20];
     29 int rt[maxn],tot;
     30 int ans,maxflow;
     31  
     32 inline void newnode(int u,int v,int w)
     33 {to[++cnt]=v,nxt[cnt]=fir[u],fir[u]=cnt,cap[cnt]=w;}
     34 inline void Add(int u,int v,int w)
     35 {newnode(u,v,w),newnode(v,u,0);}
     36  
     37 inline int find(int num)
     38 {
     39     int l=1,r=N;
     40     while(l<r)
     41     {
     42         int mid=(l+r)>>1;
     43         if(Q[mid]>=num)r=mid;
     44         else l=mid+1;
     45     }
     46     return l;
     47 }
     48  
     49 inline void Link(int now,int l,int r,int i)
     50 {
     51     if(R[i]<l||L[i]>r)return;
     52     if(L[i]<=l&&r<=R[i]){Add(i+n,T+now,INF);return;}
     53     int mid=(l+r)>>1;
     54     if(t[now].lc)Link(t[now].lc,l,mid,i);
     55     if(t[now].rc)Link(t[now].rc,mid+1,r,i);
     56 }
     57  
     58 inline void insert(int &now,int pre,int l,int r,int i)
     59 {
     60     if(!now||now==pre)now=++tot,t[now]=t[pre];
     61     if(l==r){Add(T+now,i,INF);if(pre)Add(T+now,T+pre,INF);return;}
     62     int mid=(l+r)>>1;
     63     if(A[i]<=mid)insert(t[now].lc,t[pre].lc,l,mid,i);
     64     else insert(t[now].rc,t[pre].rc,mid+1,r,i);
     65     if(t[now].lc)Add(T+now,T+t[now].lc,INF);
     66     if(t[now].rc)Add(T+now,T+t[now].rc,INF);
     67 }
     68  
     69 inline bool bfs()
     70 {
     71     memset(h,-1,sizeof h);h[S]=0;
     72     queue<int>Q;Q.push(S);
     73     while(!Q.empty())
     74     {
     75         int u=Q.front();Q.pop();
     76         for(int i=fir[u];i;i=nxt[i])
     77             if(cap[i]&&!~h[to[i]])
     78                 h[to[i]]=h[u]+1,Q.push(to[i]);
     79     }
     80     return ~h[T];
     81 }
     82  
     83 inline int dfs(int u,int flow)
     84 {
     85     int used=0;
     86     if(u==T)return flow;
     87     for(int i=fir[u];i;i=nxt[i])
     88         if(cap[i]&&h[to[i]]==h[u]+1)
     89         {
     90             int w=flow-used;
     91             w=dfs(to[i],min(w,cap[i]));
     92             cap[i]-=w,cap[opst(i)]+=w,used+=w;
     93             if(used==flow)return flow;
     94         }
     95     if(!used)h[u]=-1;
     96     return used;
     97 }
     98  
     99 inline void dinic()
    100 {while(bfs())maxflow+=dfs(S,INF);}
    101  
    102 int main()
    103 {
    104     n=getint();
    105     for(int i=1;i<=n;i++)
    106     {
    107         A[i]=getint(),ans+=B[i]=getint(),ans+=W[i]=getint();
    108         L[i]=getint(),R[i]=getint(),P[i]=getint();
    109         Q[++N]=A[i],Q[++N]=L[i],Q[++N]=R[i];
    110     }
    111     sort(Q+1,Q+N+1),N=unique(Q+1,Q+N+1)-(Q+1);
    112     T=2*n+1;
    113     for(int i=1;i<=n;i++)
    114     {
    115         A[i]=find(A[i]);
    116         L[i]=find(L[i]);
    117         R[i]=find(R[i]);
    118         Add(S,i,B[i]),Add(i,T,W[i]),Add(i,i+n,P[i]);
    119     }
    120     for(int i=1;i<=n;i++)
    121     {
    122         if(i>1)Link(rt[i-1],1,N,i);
    123         insert(rt[i],rt[i-1],1,N,i);
    124     }
    125     dinic();
    126     printf("%d
    ",ans-maxflow);
    127 }
    View Code

     

  • 相关阅读:
    算法导论--2.2分析算法
    C++对象模型
    算法导论--插入排序
    记一次Chrome冒充QQ浏览器领取奖励之行
    eclipse做界面开发
    eclipse jad 反编译 插件安装
    eclipse下web开发中缓存问题
    eclipse缓存问题
    No more “busy and acquire with NOWAIT”
    ora-00054:resource busy and acquire with nowait specified解决方法
  • 原文地址:https://www.cnblogs.com/Darknesses/p/12005969.html
Copyright © 2011-2022 走看看