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
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 }