您的位置:首页 > 其它

bzoj 4276: [ONTAK2015]Bajtman i Okrągły Robin 线段树优化建图+费用流

2017-06-17 12:03 316 查看

题意

有n个强盗,其中第i个强盗会在[a[i],a[i]+1],[a[i]+1,a[i]+2],…,[b[i]-1,b[i]]这么多段长度为1时间中选出一个时间进行抢劫,并计划抢走c[i]元。作为保安,你在每一段长度为1的时间内最多只能制止一个强盗,那么你最多可以挽回多少损失呢?

n<=5000,ai,bi<=5000

分析

每个小偷往线段树对应区间上连边然后费用流就好了。

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;

const int N=30005;
const int inf=0x3f3f3f3f;

int n,cnt,last
,dis
,ans,s,t,pre
;
bool vis
;
struct edge{int from,to,next,c,w;}e[N*100];
queue<int> q;

int read()
{
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}

void addedge(int u,int v,int c,int w)
{
e[++cnt].from=u;e[cnt].to=v;e[cnt].c=c;e[cnt].w=w;e[cnt].next=last[u];last[u]=cnt;
e[++cnt].from=v;e[cnt].to=u;e[cnt].c=0;e[cnt].w=-w;e[cnt].next=last[v];last[v]=cnt;
}

void build(int d,int l,int r)
{
if (l==r)
{
addedge(d+n,t,1,0);
return;
}
addedge(d+n,d*2+n,inf,0);addedge(d+n,d*2+1+n,inf,0);
int mid=(l+r)/2;
build(d*2,l,mid);build(d*2+1,mid+1,r);
}

void ins(int d,int l,int r,int x,int y,int z)
{
if (x>y) return;
if (l==x&&r==y)
{
addedge(z,d+n,1,0);
return;
}
int mid=(l+r)/2;
ins(d*2,l,mid,x,min(y,mid),z);
ins(d*2+1,mid+1,r,max(x,mid+1),y,z);
}

bool spfa()
{
for (int i=0;i<=t;i++) dis[i]=-inf;
dis[s]=0;q.push(s);
while (!q.empty())
{
int u=q.front();q.pop();
for (int i=last[u];i;i=e[i].next)
if (e[i].c&&dis[u]+e[i].w>dis[e[i].to])
{
dis[e[i].to]=dis[u]+e[i].w;
pre[e[i].to]=i;
if (!vis[e[i].to]) vis[e[i].to]=1,q.push(e[i].to);
}
vis[u]=0;
}
if (dis[t]>-inf) return 1;
else return 0;
}

void mcf()
{
ans+=dis[t];
int x=t;
while (x)
{
e[pre[x]].c--;
e[pre[x]^1].c++;
x=e[pre[x]].from;
}
}

int main()
{
n=read();
s=0;t=n+20005+1;cnt=1;
build(1,1,5000);
for (int i=1;i<=n;i++)
{
int l=read(),r=read(),w=read();
addedge(s,i,1,w);
ins(1,1,5000,l,r-1,i);
}
while (spfa()) mcf();
printf("%d",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: