最大值
解:
一开始还以为是一道费用流,结果是一道网络流~
果然网络流除了二分图就什么都不会了。
其实思想是很简单的,我们使用最小割。
以前也想过这样的模型:一个点的所有取值排成一排,然后跑最小割,肯定只会割1个点,而且这个点是最优的。然后我们思考对条件的限制,若
xu≤xv+d
,那么假如
u
取值为
然后我们就做完了,记得注意边界。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
struct lxy{
int next,to,flow;
}b[1000005];
struct data{
int a,b,c,l,r;
}k[55];
int n,m,s,t=11000,cnt=-1,x,y,a_,b_,c,eee;
int head[11005];
int Max=10000005;
int layer[11005];
int cir[11005];
queue <int> d;
void add(int op,int ed,int flow)
{
b[++cnt].next=head[op];
b[cnt].to=ed;
b[cnt].flow=flow;
head[op]=cnt;
}
int clac(int x)
{
return a_*x*x+b_*x+c;
}
int wei(int num,int x)
{
return (x-1)*202+num+102;
}
bool bfs()
{
memset(layer,0,sizeof(layer));
queue <int> d;
layer[s]=1;
d.push(s);
while(!d.empty())
{
int noww=d.front();
d.pop();
for(int i=head[noww];i!=-1;i=b[i].next)
if(layer[b[i].to]==0&&b[i].flow!=0)
{
layer[b[i].to]=layer[noww]+1;
d.push(b[i].to);
}
}
return layer[t];
}
int dfs(int u,int a)
{
if(u==t||a==0) return a;
int f=0;
int flow=0;
if(cir[u]==-1) cir[u]=head[u];
for(int i=cir[u];i!=-1;i=b[i].next)
{
cir[u]=i;
if(layer[u]+1==layer[b[i].to]&&b[i].flow>0)
{
f=dfs(b[i].to,min(a,b[i].flow));
b[i].flow-=f;
b[i^1].flow+=f;
flow+=f;
a=a-f;
if(a==0) break;
}
}
return flow;
}
int dinic()
{
int ans=0;
while(bfs())
memset(cir,-1,sizeof(cir)),ans=ans+dfs(s,0x7f7f7f7f);
return ans;
}
int main()
{
scanf("%d%d",&n,&m);
memset(head,-1,sizeof(head));
for(int i=1;i<=n;i++)
scanf("%d%d%d",&k[i].a,&k[i].b,&k[i].c);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&k[i].l,&k[i].r);
a_=k[i].a;b_=k[i].b;c=k[i].c;
add(s,wei(k[i].l-1,i),0x7f7f7f7f);
add(wei(k[i].l-1,i),s,0);
for(int j=k[i].l;j<=k[i].r;j++)
{
add(wei(j-1,i),wei(j,i),Max-clac(j));
add(wei(j,i),wei(j-1,i),0);
}
add(wei(k[i].r,i),t,0x7f7f7f7f);
add(t,wei(k[i].r,i),0);
}
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&eee);
for(int j=k[x].l;j<=k[x].r;j++)
if(j-eee<=k[y].r+1&&j-eee>=k[y].l)
{
add(wei(j-1,x),wei(j-eee-1,y),0x7f7f7f7f);
add(wei(j-eee-1,y),wei(j-1,x),0);
}
}
printf("%d",Max*n-dinic());
}