第十九次CCF计算机软件能力认证-乔乔和牛牛逛超市

乔乔和牛牛去逛超市了,超市里有 n n n 种商品,他们决定买一些商品回家。

但是,第 i i i 种商品一旦被选择,购买的个数就必须是 L i L_i Li 和 R i R_i Ri 之间的整数(含端点)。

某些商品之间有依赖关系,依赖关系有两种:

  1. 只有第 x x x 种商品被购买了,第 y y y 种商品才可以被购买。
  2. 只有第 x x x 种商品被购买了,第 y y y 种商品的购买个数才可以恰好是 L i L_i Li 或 R i R_i Ri。

购买一个商品带来的开心程度和这个商品购买的个数有关,若第 i i i 个商品购买了 x i x_i xi 个, x i > 0 x_i> 0 xi>0,则收益为 a i x i 2 + b i x i + c i a_ix_i^2+b_ix_i+c_i aixi2+bixi+ci,否则为 0 0 0。

现在牛牛和乔乔想知道逛超市的最大总开心程度是多少。

输入格式

第一行包含两个整数 n , m n, m n,m,表示商品数量和依赖关系数量。

接下来 n n n 行,每行包含五个整数 L i , R i , a i , b i , c i L_i,R_i,a_i,b_i,c_i Li,Ri,ai,bi,ci,描述一个商品。

接下来 m m m 行,每行包含三个整数 z , x , y z, x, y z,x,y,表示第 x x x 种商品对第 y y y 种商品存在第 z z z 种关系。

输出格式

输出一个整数,表示最大总开心程度。

数据范围

0 ≤ n ≤ 1 0 4 0 \le n \le 10^4 0≤n≤104,
0 ≤ m ≤ 1 0 5 0 \le m \le 10^5 0≤m≤105,
1 ≤ L i ≤ R i ≤ 1 0 4 1 \le L_i \le R_i \le 10^4 1≤Li≤Ri≤104,
− 5 ≤ a i ≤ 5 -5 \le a_i \le 5 −5≤ai≤5,
− 1 0 4 ≤ b i , c i ≤ 1 0 4 -10^4 \le b_i,c_i \le 10^4 −104≤bi,ci≤104,
L i + 1 ≤ R i − 1 L_i+1 \le R_i-1 Li+1≤Ri−1
1 ≤ x , y ≤ n 1 \le x,y \le n 1≤x,y≤n,
1 ≤ z ≤ 2 1 \le z \le 2 1≤z≤2,

对于 20 % 20\% 20% 的数据, n ≤ 10 , R i ≤ 5 n \le 10,R_i \le 5 n≤10,Ri≤5;

对于 40 % 40\% 40% 的数据, n ≤ 10 n \le 10 n≤10;

对于另外 20 % 20\% 20% 的数据,只有第 1 1 1 种依赖关系。

输入样例:
2 2
1 10 -2 3 -5
1 10 2 3 5
2 1 2
1 2 1
输出样例:
231
样例解释

第 1 1 1 种商品购买 1 1 1 个,第 2 2 2 种商品购买 10 10 10 个。

这个题非常恶心:对于我这个只会一些比较初级的算法的小白而言连暴力蒙20分都做不到。。就是只考虑第一种约束情况,也需要用到图论的最大权闭合图 参考代码如下:

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

vector<int>edges[20010],ednum[20010];
long long f[400010],cur[20010],depth[20010],v1[20010],v2[20010];
long long n,m,idx=-1,S,T,tot=0;

long long get(long long a,long long b,long long c,long long l,long long r){
    if(a==0) return max(b*l+c,b*r+c);
    long long i=(-b)/(2*a),k=i+1,j=i-1;
    long long res=max(a*l*l+b*l+c,a*r*r+b*r+c);
    if(i>=l&&i<=r) res=max(res,a*i*i+b*i+c);
    if(k>=l&&k<=r) res=max(res,a*k*k+b*k+c);
    if(j>=l&&j<=r) res=max(res,a*j*j+b*j+c);
    return res;
}

void add(int a,int b,int c){
    edges[a].push_back(b),ednum[a].push_back(++idx),f[idx]=c;
    edges[b].push_back(a),ednum[b].push_back(++idx),f[idx]=0;
}

bool bfs(){
    memset(depth,-1,sizeof depth);
    depth[S]=0,cur[S]=0;
    queue<int>nodes;
    nodes.push(S);
    while(!nodes.empty()){
        int temp=nodes.front();
        nodes.pop();
        for(int i=0;i<edges[temp].size();i++){
            int t=edges[temp][i],e=ednum[temp][i];
            if(depth[t]!=-1||f[e]==0) continue;
            cur[t]=0;
            depth[t]=depth[temp]+1;
            if(t==T) return true;
            nodes.push(t);
        }
    }
    return false;
}

long long dfs(long long now,long long limit){
    if(now==T) return limit;
    long long flow=0;
    for(int i=cur[now];i<edges[now].size()&&flow<limit;i++){
        int t=edges[now][i],e=ednum[now][i];
        cur[now]=i;
        if(depth[t]!=depth[now]+1||f[e]==0) continue;
        long long u=dfs(t,min(limit-flow,f[e]));
        if(u==0) depth[t]=-1;
        flow+=u,f[e]-=u,f[e^1]+=u;
    }
    return flow;
}

long long dinic(){
    long long res=0;
    while(bfs()) res+=dfs(S,0x3f3f3f3f3f3f3f3f);
    return res;
}


int main(){
    cin>>n>>m;
    S=0,T=2*n+1;
    for(int i=1;i<=n;i++){
        int l,r,a,b,c;
        cin>>l>>r>>a>>b>>c;
        v1[i]=get(a,b,c,l+1,r-1);
        v2[i]=get(a,b,c,l,r)-v1[i];
        add(i+n,i,0x3f3f3f3f);
    }
    for(int i=1;i<=n;i++){
        if(v1[i]>0) add(S,i,v1[i]),tot+=v1[i];
        else if(v1[i]<0) add(i,T,-v1[i]);
        if(v2[i]>0) add(S,i+n,v2[i]),tot+=v2[i];
        else if(v2[i]<0) add(i+n,T,-v2[i]);
    }
    for(int i=0;i<m;i++){
        int z,x,y;
        cin>>z>>x>>y;
        if(z==1) add(y,x,0x3f3f3f3f);
        else add(y+n,x,0x3f3f3f3f);
    }
    cout<<tot-dinic();
    return 0;
}
相关推荐
liuming199212 分钟前
Halcon中histo_2dim(Operator)算子原理及应用详解
图像处理·人工智能·深度学习·算法·机器学习·计算机视觉·视觉检测
sc写算法29 分钟前
Hash 映射
数据结构·算法·哈希算法
雅妮yyn41 分钟前
头歌数据结构-排序的实现及其应用
数据结构·算法
煤泥做不到的!42 分钟前
挑战一个月基本掌握C++(第六天)了解函数,数字,数组,字符串
开发语言·c++
云边有个稻草人43 分钟前
【优选算法】—移动零(双指针算法)
算法·排序算法·双指针算法
智能与优化1 小时前
C++打造局域网聊天室第十一课: 程序关闭及线程的结束
开发语言·c++
小墨&晓末1 小时前
【PythonGui实战】自动摇号小程序
python·算法·小程序·系统安全
小王爱吃月亮糖2 小时前
C++进阶-1-单继承、多继承、虚继承
开发语言·c++·笔记·学习·visual studio
落魄君子2 小时前
SVM分类-支持向量机(Support Vector Machine)
神经网络·算法·支持向量机·分类
Am心若依旧4092 小时前
[c++进阶(三)]单例模式及特殊类的设计
java·c++·单例模式