题目大意:。。。自己看
从源点出发,分别向汇点连两条流量为a和b的边,跑最大流即是a+b。
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 10
#define S 1
#define T 2
#define INF 0x3f3f3f3f
using 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;
}
。。。上面那个是开玩笑的
首先考虑朴素一些的做法
将每个点i拆成两个点i和i',i'向i连一条流量为p的边
从S向i连一条流量为w的边 从i向T连一条流量为b的边
如果j选白点i选黑点时i会变得奇♂怪起来的话,就从j到i'连一条流量为INF的边
这样就保证了如果j选择了白色,i就要么选择白色,要么变得奇♂怪
但是这样建图的话,j->i'的边数可以达到O(n^2)
我们可以考虑建一棵权值线段树,从j向相应叶节点连边,从i‘覆盖的区间向i’连边
但是这样做我们无视了j<i这个条件
因此我们将这棵线段树改成可持久化线段树即可
每新建一条链,从旧版本的每个点和点i分别向新建的链上节点连边
然后去上一个版本查询相应区间并连边即可
#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);
dpt[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]);
puts("--------------------------------------");
DFS(S);
puts("--------------------------------------");
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 mempool[M],*C=mempool;
C->ls=_;
C->rs=__;
C->val=___;
C->num=++cnt;
return C++;
}
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;
else
re=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&&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,&l,&r,&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;
}