• 杂题选讲


    首先有一些神奇的东西。

    有一类问题可以转化成形如$minimizesum_{u,v} max(h_u-h_v+w_{u,v},0)c_{u,v}$,其中h是任意值

    然后这个和最大费用循环流等价,就是u到v连一条$(c_{u,v},w_{u,v})$的边,然后消一下正环,直接跑就完了。。。

    有一道例题 CF1307G

    大概是要求一个这样的东西

    $minimize d_n-d_1$

    $s.t.$     $d_v<=d_u+w_{u,v}+x_{u,v},sum x_{u,v}<=x,x_{u,v}>=0$

    然后如果设答案下届为L,问题转化为

    $minimize sum x_{u,v}$

    $s.t.$     $d_v<=d_u+w_{u,v}+x_{u,v},d_n-d_1>=L,x_{u,v}>=0$

    这个可以试着转化一下就是上面的形式了(将$d$视为$h$)

    但是并不能二分,可以先不建流量为L的边直接跑,然后可以得到一个费用关于流量的函数f(x)。

    我们要求加上一个斜率为L的直线,使得$forall f(i)+L*i<=x$均成立,直接连立解出L即可。

    复杂度$O(n^4+qn)$

    #include<bits/stdc++.h>
    using namespace std;
    const int maxm=55*55*55;
    int head[maxm],to[maxm],nxt[maxm],val[maxm],fw[maxm],cnt=1,t[maxm];
    int q[maxm],d[maxm],n,m,pre[maxm];
    bool v[maxm];
    inline void link(int a,int b,int c){
        to[++cnt]=b,nxt[cnt]=head[a],head[a]=cnt,fw[cnt]=1,val[cnt]=c;
        to[++cnt]=a,nxt[cnt]=head[b],head[b]=cnt,val[cnt]=-c;
    }
    inline bool SPFA(){
        for(int i=1;i<=n;++i) d[i]=-0x3f3f3f3f;d[n]=0; int h,t;q[h=t=0]=n;
        while(h<=t){
            int x=q[h++];
            for(int i=head[x];i;i=nxt[i]) if(fw[i]){
                int y=to[i];
                if(d[y]<d[x]+val[i]) {
                    pre[y]=i,d[y]=d[x]+val[i];
                    if(!v[y]) q[++t]=y,v[y]=1;
                }
            }
            v[x]=0;
        }
        return d[1]!=-0x3f3f3f3f;
    }
    int main(){
        cin>>n>>m;int res=0,tot=0,q;
        while(m--){
            int a,b,c;cin>>a>>b>>c;
            link(b,a,-c);
        }
        while(SPFA()){
            int res=0;
            for(int i=1;i!=n;i=to[pre[i]^1]) res+=val[pre[i]],--fw[pre[i]],++fw[pre[i]^1];
            t[++tot]=res;t[tot]+=t[tot-1];//cout<<t[tot]<<endl;
        }cin>>q;//cout<<tot<<endl;
        while(q--){
            int x;scanf("%d",&x);
            double ans=1e16;
            for(int i=1;i<=tot;++i) ans=min(ans,1.0*(x-t[i])/i);//,cout<<x-t[i]<<endl;
            printf("%lf
    ",ans);
        }
        return 0;
    }
    View Code

    有一个东西叫保序回归,他的模型大概是有n个变量$x_i$,有m个限制形如要求$y_i<y_j$,变量的变化有代价函数f(x),然后要最小化$sum f(|y_i-x_i|)$

    做法:首先整体二分,假设当前参数为$solve(l,r,S)$,然后$mid=l+r>>1$,考虑以mid为界来划分S集合,也就是将S划分为A和B。

    就是以是否超过mid为界,那么考虑每个点,如果变成<=mid的,就和源点连一条$f(|mid-x_i|)$,再和汇点连一条$f(|mid+1-x_i|)$的边,

    然后对于那些限制可以直接看成最大权闭合子图,最后看和源汇点的联通来判断分到左右儿子,边界有一些特判。

    (一点都不会证明)

    然后有一道ZJOI的题 「ZJOI2020」抽卡

    咕了

  • 相关阅读:
    葡萄城报表介绍:数据报表的七个原则
    while(scanf("%d",&n)!=EOF)
    不容易系列之(3)—— LELE的RPG难题
    错排公式
    _​_​i​n​t​6​4​ ​与​l​o​n​g​ ​l​o​n​g​ ​i​n​t
    杭电ACM 2046 阿牛的EOF牛肉串
    C++Builder 中使用 __int64 整数的问题
    折线分平面——杭电2050
    复合梯形公式与复合辛普森公式求积分
    两套蓝桥杯热身题
  • 原文地址:https://www.cnblogs.com/hzoi-kx/p/13374341.html
Copyright © 2020-2023  润新知