zoukankan      html  css  js  c++  java
  • luogu3826 [NOI2017]蔬菜

    [NOI2017]蔬菜

    太神了写不来

    一眼看出来是个网络流(费用流),口胡一个建图(勿轻信,未实践):对每一天用一个节点来表示,卖什么菜则用连边表示,对于当前的蔬菜,源点向这种蔬菜未完全变质的天连边,容量为在这一天变质的蔬菜量,费用为(a_i),特别的对于(s_i),我们在最后一天单独拆一条边,流量为1,费用为(a_i+s_i),同时每一天向前一天连一条容量为(inf),费用为(0)的边,表示最迟在这一天必须被卖出去的蔬菜可以放在前面被卖出,最后每一天向汇点连容量为(m),费用为(0)的边,这样应该可以获得(56-60pts)

    那么如何优化呢?我们可以模拟这个费用流的过程。注意到这样一个重要的性质:在前(i-1)天卖出去蔬菜一定是前(i)天卖出去的蔬菜的子集,于是在上面的费用流中由(S)连出去的那一部分是不会发生退流操作的,于是我们可以用一个堆来维护每一种蔬菜当前的价值,每次从取出一个最大的元素,看它是否能在一个合法的天数之前被卖掉,这个可以用堆+并查集维护

    于是就做完了QAQ,这个模拟费用流还是比较好写的,关键点是注意到不会发生退流操作

    #include<iostream>
    #include<string.h>
    #include<string>
    #include<stdio.h>
    #include<algorithm>
    #include<vector>
    #include<math.h>
    #include<queue>
    #include<set>
    #include<map>
    using namespace std;
    #define int long long
    typedef long long ll;
    typedef long double db;
    const int N=100000;
    const db pi=acos(-1.0);
    #define lowbit(x) (x)&(-x)
    #define sqr(x) (x)*(x)
    #define rep(i,a,b) for (register int i=a;i<=b;i++)
    #define per(i,a,b) for (register int i=a;i>=b;i--)
    #define fir first
    #define sec second
    #define mp(a,b) make_pair(a,b)
    #define pb(a) push_back(a)
    #define maxd 998244353
    #define eps 1e-8
    
    struct node{
        int val,id;
    };
    bool operator <(node p,node q) {return p.val<q.val;}
    priority_queue<node> q;
    struct vegetable{
        int a,c,x,s;
    }a[100100];
    int n,m,qcnt,fa[100100],cnt[100100];
    ll ans[100100];
    
    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;
    }
    
    int find(int x)
    {
        if (fa[x]==x) return fa[x];
        fa[x]=find(fa[x]);
        return fa[x];
    }
    
    signed main()
    {
        n=read();m=read();qcnt=read();
        rep(i,1,n)
        {
            a[i].a=read();a[i].s=read();a[i].c=read();a[i].x=read();
            if (a[i].c) q.push((node){a[i].s+a[i].a,i});
        }
        rep(i,1,N) fa[i]=i;
        ll sum=0;
        rep(i,1,N)
        {
            int j;
            for (j=1;j<=m && !q.empty();j++)
            {
                node now=q.top();q.pop();
                int lat;
                if (!a[now.id].x) lat=N;
                else lat=min(N,(a[now.id].c-1)/a[now.id].x+1);
                int pos=find(lat);
                //cout << pos << " " << lat << endl;
                if (!pos) {j--;continue;}cnt[pos]++;
                if (cnt[pos]==m) fa[pos]=find(pos-1);
                sum+=now.val;a[now.id].c--;
                if (a[now.id].c) q.push((node){a[now.id].a,now.id});
            }
            //cout << endl;
            ans[i]=sum;
        }
        while (qcnt--) printf("%lld
    ",ans[read()]);
        return 0;
    }
    
  • 相关阅读:
    html5 localstorage本地存储
    如何在源码里修改openwrt root密码
    openwrt-scripts/config/mconf: Syntax error: “(” unexpected错误解决
    HTML5获取地理位置信息
    Mysql 查看连接数,状态 最大并发数(赞)
    晨读笔记:CSS3选择器之属性选择器
    CSS3选择器之属性选择器
    js判断浏览器类型
    javascript json字符串与对象相互转换
    手机端html5触屏事件(touch事件)
  • 原文地址:https://www.cnblogs.com/encodetalker/p/11141341.html
Copyright © 2011-2022 走看看