bzoj 3218: 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
非常强的主席树优化网络流
我觉得这篇博客对于主席树优化的原理说的不错
这个对于建图方法有说明
只有转载链接才能勉强维持的了生活这样子
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<cmath>
  6 #include<queue>
  7 using namespace std;
  8 struct Node
  9 {
 10   int next,to,cap;
 11 }edge[2000001];
 12 int head[100001],num=1,n,inf=2e9;
 13 int ch[2000001][2],root[50001],pos,dist[100001],cur[100001],ans;
 14 int a[5001],l[5001],r[5001],d[15001],siz;
 15 void add(int u,int v,int c)
 16 {
 17   num++;
 18   edge[num].next=head[u];
 19   head[u]=num;
 20   edge[num].to=v;
 21   edge[num].cap=c;
 22   num++;
 23   edge[num].next=head[v];
 24   head[v]=num;
 25   edge[num].to=u;
 26   edge[num].cap=0;
 27 }
 28 void query(int rt,int l,int r,int L,int R,int id)
 29 {
 30   if (!rt) return;
 31   if (l>=L&&r<=R)
 32     {
 33       add(rt,id+n,inf);
 34       return;
 35     }
 36   int mid=(l+r)/2;
 37   if (L<=mid) query(ch[rt][0],l,mid,L,R,id);
 38   if (R>mid) query(ch[rt][1],mid+1,r,L,R,id);
 39 }
 40 void update(int rt1,int &rt2,int l,int r,int x,int id)
 41 {
 42   rt2=++pos;
 43   ch[rt2][0]=ch[rt1][0];ch[rt2][1]=ch[rt1][1];
 44   if (rt1)
 45   add(rt1,rt2,inf);add(id,rt2,inf);
 46   if (l==r)
 47     return;
 48   int mid=(l+r)/2;
 49   if (x<=mid) update(ch[rt1][0],ch[rt2][0],l,mid,x,id);
 50   else update(ch[rt1][1],ch[rt2][1],mid+1,r,x,id);
 51 }
 52 bool bfs(int S,int T)
 53 {int i;
 54   queue<int>Q;
 55   for (i=0;i<=pos;i++)
 56     dist[i]=-1;
 57   Q.push(S);
 58   dist[S]=1;
 59   while (Q.empty()==0)
 60     {
 61       int u=Q.front();
 62       Q.pop();
 63       for (i=head[u];i!=-1;i=edge[i].next)
 64     {
 65       int v=edge[i].to;
 66       if (edge[i].cap&&dist[v]==-1)
 67         {
 68           dist[v]=dist[u]+1;
 69           Q.push(v);
 70         }
 71     }
 72     }
 73   if (dist[T]==-1) return 0;
 74   return 1;
 75 }
 76 int dfs(int x,int des,int flow)
 77 {
 78   int res=0;
 79   if (flow<=0||x==des) return flow;
 80   for (int &i=cur[x];i!=-1;i=edge[i].next)
 81     {
 82       int v=edge[i].to;
 83       if (dist[v]==dist[x]+1&&edge[i].cap)
 84     {
 85       int tmp=dfs(v,des,min(flow-res,edge[i].cap));
 86       if (tmp<=0) continue;
 87       edge[i].cap-=tmp;
 88       edge[i^1].cap+=tmp;
 89       res+=tmp;
 90       if (res==flow) return res;
 91     }
 92     }
 93   return res;
 94 }
 95 int Maxflow()
 96 {int i,as=0,s=0;
 97   while (bfs(0,2*n+1))
 98     {
 99       as=0;
100       for (i=0;i<=pos;i++)
101     cur[i]=head[i];
102       while (as=dfs(0,2*n+1,inf)) s+=as;
103     }
104   return s;
105 }
106 int main()
107 {int i,b,w,p;
108   cin>>n;
109   memset(head,-1,sizeof(head));
110   for (i=1;i<=n;i++)
111     {
112       scanf("%d%d%d%d%d%d",&a[i],&b,&w,&l[i],&r[i],&p);
113       ans+=b+w;
114       add(0,i,w);
115       add(n+i,i,p);
116       add(i,2*n+1,b);
117       d[i]=a[i];d[n+i]=l[i];d[n+n+i]=r[i];
118     }
119   sort(d+1,d+3*n+1);
120   siz=unique(d+1,d+3*n+1)-d-1;
121   for (i=1;i<=n;i++)
122     {
123       a[i]=lower_bound(d+1,d+siz+1,a[i])-d;
124       l[i]=lower_bound(d+1,d+siz+1,l[i])-d;
125       r[i]=lower_bound(d+1,d+siz+1,r[i])-d;
126     }
127   pos=2*n+1;
128   for (i=1;i<=n;i++)
129     {
130       query(root[i-1],1,siz,l[i],r[i],i);
131       update(root[i-1],root[i],1,siz,a[i],i);
132     }
133   cout<<ans-Maxflow();
134 }

 

posted @ 2018-01-09 22:09  Z-Y-Y-S  阅读(410)  评论(0编辑  收藏  举报