Bzoj 3218 A + B problem to persist segment tree + min cut

Source: Internet
Author: User

The main idea of the topic: ... See for yourself

From the source point, the two flows to the meeting point are the sides of A and b respectively, and the maximum flow is a+b.

Code:

#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 10# Define S 1#define T 2#define INF 0x3f3f3f3fusing namespace std;struct abcd{int to,f,next;} Table[100];int head[m],tot=1;void Add (int x,int y,int z) {table[++tot].to=y;table[tot].f=z;table[tot].next=head[x]; Head[x]=tot;} void Link (int x,int y,int z) {Add (x, y, z); ADD (y,x,0);}      namespace max_flow{int dpt[m];          BOOL BFS () {static int q[m];          int i,r=0,h=0;          memset (dpt,-1,sizeof DPT);          Q[++r]=s;dpt[s]=1;              while (r!=h) {int x=q[++h];                      for (I=head[x];i;i=table[i].next) if (table[i].f&&!~dpt[table[i].to]) {                      dpt[table[i].to]=dpt[x]+1;                      q[++r]=table[i].to;                  if (table[i].to==t) return true;      }} return false;     } int dinic (int x,int flow) {int i,left=flow;          if (x==t) return flow;              for (I=head[x];i&&left;i=table[i].next) if (table[i].f&&dpt[table[i].to]==dpt[x]+1)                  {int Temp=dinic (table[i].to,min (LEFT,TABLE[I].F));                  if (!temp) dpt[table[i].to]=-1;                  Left-=temp;                  Table[i].f-=temp;              Table[i^1].f+=temp;      } return flow-left; }}int Main () {using namespace Max_flow;int i,x,ans=0;for (i=1;i<=2;i++) scanf ("%d", &x), Link (S,t,x), while (BFS () ) Ans+=dinic (s,inf); Cout<<ans<<endl;return 0;}

。。。 The one above is a joke.

First, consider some simple practices

Each point I is split into two points I and I ', I ' to I even a flow for the side of P

An edge with a flow of W from S to I with a flow of b from I to t

If j selected White point I selected black point I will become odd ♂ strange, from J to I ' even a flow to the edge of the INF


This ensures that if J chooses white, I either chooses white, or becomes odd ♂ strange.

However, the j->i ' number of sides can reach O (n^2).


We can consider building a tree of weight segments from J to the corresponding leaf nodes, from the I ' covered interval to the I ' Edge


But in doing so, we ignore the j<i condition.

So we're going to change this segment tree to a tree of durable segments.

Each new chain, from the previous version of each point and point I to the new link node edge

Then go to the previous version to query the corresponding interval and connect the edge can

#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 200200#  Define S 0#define T 200199#define INF 0x3f3f3f3f#define P1 (x) ((x) *2-1) #define P2 (x) ((x) <<1) using namespace Std;int N,m,cnt;long long ans;namespace max_flow{struct abcd{int To,f,next;} Table[1001001];int head[m],tot=1;int dpt[m];void Add (int x,int y,int z) {Table[++tot].to=y;table[tot].f=z;table[tot]. Next=head[x];head[x]=tot;} void Link (int x,int y,int z) {Add (x, y, z); ADD (y,x,0);} BOOL BFS () {static int q[m];int i,r=0,h=0;memset (dpt,-1,sizeof DPT);DP t[s]=1;q[++r]=s;while (r!=h) {int x=q[++h];for (i= Head[x];i;i=table[i].next) if (table[i].f&&!~dpt[table[i].to]) {Dpt[table[i].to]=dpt[x]+1;q[++r]=table[i] . To;if (Table[i].to==t) return true;}} return false;} int dinic (int x,int flow) {int i,left=flow;if (x==t) return flow;for (I=head[x];i&&left;i=table[i].next) if ( table[i].f&&dpt[table[i].to]==dpt[x]+1) {int temp=dinic (table[i].to,min (LEFT,TABLE[I].F)); Left-=temp;tabLe[i].f-=temp;table[i^1].f+=temp;} if (left) Dpt[x]=-1;return Flow-left;} void DFS (int x) {static int v[m];v[x]=1;if (x<=n<<1) printf ("%d\n", x+1>>1); for (int i=head[x];i;i=table[ I].next) if (table[i].f&&!v[table[i].to]) DFS (table[i].to);} void Debug () {static int s[m],t[m];int i;for (i=head[s];i;i=table[i].next) if (table[i].to<=n<<1) s[table[i]. To+1>>1]= (table[i].f?-1:1); for (I=head[t];i;i=table[i].next) if (table[i].to<=n<<1) t[table[i].to+1 >>1]= (Table[i^1].f?-1:1), for (i=1;i<=n;i++) printf ("%d%d%d\n", I,s[i],t[i]);p UTS ("---------------------- ----------------");D FS (S);p UTS ("--------------------------------------"); for (I=HEAD[P2 (6)];i;i=table[i].next) if (TABLE[I].TO==P1 (6)) cout<<table[i].f<<endl;puts ("--------------------------------------");}} struct Segtree{segtree *ls,*rs;int val,num;void* operator new (size_t,segtree *_,segtree *__,int ___) {static Segtree memp Ool[m],*c=mempool; c->ls=_; c->rs=__; c->val=___; C->num=++cnt;returnC + +;} segtree* build_tree (int x,int y,int pos,int from) {using namespace Max_flow;int mid=x+y>>1; Segtree *re;if (x==y) re=new (0x0,0x0,val+1) Segtree;else if (pos<=mid) re=new (Ls->build_tree (X,mid,pos,from), RS , val+1) segtree;elsere=new (Ls,rs->build_tree (Mid+1,y,pos,from), val+1) Segtree; Link (From,re->num,inf); Link (Num,re->num,inf); return re;} void Get_ans (int x,int y,int l,int r,int to) {using namespace Max_flow;int mid=x+y>>1;if (!val) return; if (x==l&& Amp;y==r) {Link (num,to,inf); return;} if (r<=mid) Ls->get_ans (x,mid,l,r,to), else if (l>mid) Rs->get_ans (mid+1,y,l,r,to), Else Ls->get_ans (x, Mid,l,mid,to), Rs->get_ans (Mid+1,y,mid+1,r,to);}} *tree[5050];int Main () {using namespace Max_flow;int i,a,b,w,l,r,p;cin>>n;cnt=p2 (n); Tree[0]=new (0x0,0x0,0) Segtree;tree[0]->ls=tree[0]->rs=tree[0];for (i=1;i<=n;i++) {scanf ("%d%d%d%d%d%d", &a,&b,&w, &AMP;L,&AMP;R,&AMP;P); Link (S,P1 (i), W); Link (P1 (i), t,b); Tree[i]=tree[i-1]->build_tree (0,1000000000,A,P1 (i)); Tree[i-1]->get_ans (0,1000000000,L,R,P2 (i)); Link (P2 (i), P1 (i), p); ans+=w+b;} while (BFS ())) ans-=dinic (S,inf);//debug (); Cout<<ans<<endl;return 0;}


Bzoj 3218 A + B problem to persist segment tree + min cut

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.