【CF434D】Nanami's Power Plant 最小割

【CF434D】Nanami's Power Plant

题意:有n个二次函数$y=a_ix^2+b_ix+c_i$($a_i,b_i,c_i$是整数),第i个函数要求x的取值在$[l_i,r_i]$之间且为整数。你需要确定每个函数的x的取值,使得所有函数的函数值之和最大。还有m个限制,每条限制形如$u,v,d$,表示$x_u\le x_v+d$。求最大函数值之和。

$n\le 50,m\le 100,-100\le l_i\le r_i\le 100$

题解:傻逼了连切糕都忘了。

对于一个方程,我们把它的所有可能取值按照x从小到大串成一串,首尾分别与S和T相连,其中第i个点和第i+1个点的边的容量为当$x=l+i-1$时的函数值(由于可能存在负数,我们给每条边的权值都加上一个大数,最后再把这个大数减去)。对于限制u,v,d,我们从u中所有代表$x_u=i$的点向v中代表$x_v=i-d$的点连一条容量inf的边,便完成了限制。

 

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
typedef long long ll;
const ll big=1ll<<30;
const ll inf=1ll<<50;
int n,m,tot,S,T,cnt;
ll ans;
int L[60],R[60],to[200010],nxt[200010],head[12000],d[12000];
int p[60][210];
ll val[200010],A[60],B[60],C[60];
queue<int> q;
inline void add(int a,int b,ll c)
{
	to[cnt]=b,val[cnt]=c,nxt[cnt]=head[a],head[a]=cnt++;
	to[cnt]=a,val[cnt]=0,nxt[cnt]=head[b],head[b]=cnt++;
}
ll dfs(int x,ll mf)
{
	if(x==T)	return mf;
	int i;
	ll temp=mf,k;
	for(i=head[x];i!=-1;i=nxt[i])	if(val[i]&&d[to[i]]==d[x]+1)
	{
		k=dfs(to[i],min(temp,val[i]));
		if(!k)	d[to[i]]=-1;
		temp-=k,val[i]-=k,val[i^1]+=k;
		if(!temp)	break;
	}
	return mf-temp;
}
inline int bfs()
{
	while(!q.empty())	q.pop();
	int i,u;
	memset(d,0,sizeof(d));
	q.push(S),d[S]=1;
	while(!q.empty())
	{
		u=q.front(),q.pop();
		for(i=head[u];i!=-1;i=nxt[i])	if(val[i]&&!d[to[i]])
		{
			d[to[i]]=d[u]+1;
			if(to[i]==T)	return 1;
			q.push(to[i]);
		}
	}
	return 0;
}
int main()
{
	//freopen("cf434D.in","r",stdin);
	scanf("%d%d",&n,&m);
	S=0,T=tot=1;
	int i,j,a,b,c;
	memset(head,-1,sizeof(head));
	for(i=1;i<=n;i++)	scanf("%lld%lld%lld",&A[i],&B[i],&C[i]);
	for(i=1;i<=n;i++)
	{
		scanf("%d%d",&L[i],&R[i]);
		add(S,tot+1,inf);
		for(j=L[i];j<=R[i];j++)
		{
			p[i][j-L[i]]=++tot;
			add(tot,tot+1,big-(A[i]*j*j+B[i]*j+C[i]));
		}
		p[i][R[i]-L[i]+1]=++tot;
		add(tot,T,inf);
	}
	for(i=1;i<=m;i++)
	{
		scanf("%d%d%d",&a,&b,&c);
		for(j=max(L[b],L[a]-c);j<=min(R[b],R[a]-c)+1;j++)
		{
			add(p[a][j+c-L[a]],p[b][j-L[b]],inf);
		}
	}
	while(bfs())	ans+=dfs(S,inf);
	printf("%lld",big*n-ans);
	return 0;
}

 

posted @ 2018-04-05 17:23 CQzhangyu 阅读(...) 评论(...) 编辑 收藏