• 2020杭电多校第二场 New Equipments(费用流)


    题目

    roblem Description
    Little Q's factory recently purchased m pieces of new equipment, labeled by 1,2,…,m.

    There are n workers in the factory, labeled by 1,2,…,n. Each worker can be assigned to no more than one piece of equipment, and no piece of equipment can be assigned to multiple workers. If Little Q assigns the i-th worker to the j-th piece of equipment, he will need to pay ai×j2+bi×j+ci dollars.

    Now please for every k (1≤k≤n) find k pairs of workers and pieces of equipment, then assign workers to these pieces of equipment, such that the total cost for these k workers is minimized.

    Input
    The first line of the input contains a single integer T (1≤T≤10), the number of test cases.

    For each case, the first line of the input contains two integers n and m (1≤n≤50, n≤m≤108), denoting the number of workers and the number of pieces of equipment.

    Each of the following n lines contains three integers ai,bi and ci (1≤ai≤10, −108≤bi≤108, 0≤ci≤1016, b2i≤4aici), denoting a worker.

    Output
    For each test case, output a single line containing n integers, the k-th (1≤k≤n) of which denoting the minimum possible total cost for k pairs of workers and pieces of equipment.

    Sample Input
    1
    3 5
    2 3 10
    2 -3 10
    1 -1 4

    Sample Output
    4 15 37

    思路

    每个人都会对应一个函数,我们有n个人,但是一个机器只能给一个人,那么我们要费用尽可能小,所以我们考虑n个函数每个函数去n个点,那么完成匹配的机器必然在这些点里面,由幼儿园学过的二次函数知识,我们可以三分求出最低值已经附近最小的n个值,求完n*n个点后,建图跑最小费用最大流就好了,费用即为答案。

    代码实现

    #include<cstdio>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<map>
    #include<iostream>
    #include<cstring>
    #include<unordered_map>
    #include<cmath>
    using namespace std;
    #define rep(i,f_start,f_end) for (int i=f_start;i<=f_end;++i)
    #define per(i,n,a) for (int i=n;i>=a;i--)
    #define MT(x,i) memset(x,i,sizeof(x) )
    #define rev(i,start,end) for (int i=start;i<end;i++)
    #define inf 0x3f3f3f3f
    #define mp(x,y) make_pair(x,y)
    #define lowbit(x) (x&-x)
    #define MOD 1000000007
    #define exp 1e-8
    #define N 1000005 
    #define fi first 
    #define se second
    #define pb push_back
    typedef long long ll;
    typedef vector <int> VI;
    typedef pair<int ,int> PII;
    typedef pair<int ,PII> PIII;
    ll gcd (ll a,ll b) {return b?gcd (b,a%b):a; }
    inline int read() {
        char ch=getchar(); int x=0, f=1;
        while(ch<'0'||ch>'9') {
            if(ch=='-') f=-1;
            ch=getchar();
        } while('0'<=ch&&ch<='9') {
            x=x*10+ch-'0';
            ch=getchar();
        } return x*f;
    }
    const int maxn=2e5+10;
    ll s,t,n,m,cnt=1,maxflow,head[maxn];
    ll dis[maxn],vis[maxn],pre[maxn],incf[maxn],ans;
    struct edge {
        ll v,flow,next,cost;
    }e[maxn];
    
    inline void add (ll u,ll v,ll flow,ll cost) {
         e[++cnt].v=v;
         e[cnt].flow=flow;
         e[cnt].next=head[u];
         e[cnt].cost=cost;
         head[u]=cnt;
    }
    
    inline void add_edge (ll u,ll v,ll flow,ll cost) {
        add (u,v,flow,cost);
        add (v,u,0,-cost);
    }
    
    inline void init () {
        MT (head,0);
        MT (pre,-1);
        MT (incf,0);
    
        cnt=1,ans=0;
    }
    
    bool spfa () {
        queue <int> q;
        q.push (s);
        MT (dis,0x3f);
        MT (vis,0);
        dis[s]=0; incf[s]=1ll<<62;
        vis[s]=1; 
        while (q.size ()) {
            int x=q.front (); q.pop ();
            vis[x]=0;
            for (int i=head[x];i;i=e[i].next) {
                int v=e[i].v;
                if (dis[v]>dis[x]+e[i].cost&&e[i].flow) {
                    dis[v]=dis[x]+e[i].cost;
                    incf[v]=min (incf[x],e[i].flow);
                    pre[v]=i;
                    if (!vis[v]) {
                        q.push (v);
                        vis[v]=1;
                    }
                }
            }
        }
        if (dis[t]==0x3f3f3f3f3f3f3f3f) return false;
        return true;
    }
    
    int match[55][55];
    ll a[55],b[55],c[55];
    
    inline void mcmf () {
        int x=t;
        while (x!=s) {
            int i=pre[x];
            e[i].flow-=incf[t];
            e[i^1].flow+=incf[t];
            x=e[i^1].v;
        }
        ans+=incf[t]*dis[t];
        maxflow+=incf[t];
    }
    
    ll f (int i,ll x) {
        return a[i]*x*x+b[i]*x+c[i];
    }
    
    inline void solve () {
        cin>>n>>m;
        init ();
        rep (i,1,n) {
            scanf ("%lld%lld%lld",&a[i],&b[i],&c[i]);
            int l=1,r=m;
            int mid=1;
            while (l<r) {
                int m1= (2*l+r)/3;
                int m2= (l+2*r+2)/3;
                if (f(i,m1)>f(i,m2)) l=m1+1;
                else r=m2-1;
            }
            if (f(i,l)<f(i,r)) mid=l;
            else mid=r;
            l=mid-1,r=mid+1;
            match[i][1]=mid;
            rep (j,2,n) {
               if (f(i,l)<f(i,r)) {
                   if (l>=1&&l<=m) match[i][j]=l--;
                   else match[i][j]=r++;
               }
               else {
                   if (r>=1&&r<=m) match[i][j]=r++;
                   else match[i][j]=l--;
               }
            }
        }
        unordered_map <int,int> mp;
        int tot=0;
        rep (i,1,n) 
         rep (j,1,n) if (!mp[match[i][j]]) mp[match[i][j]]=++tot;
        s=0,t=tot+n+1;
        rep (i,1,n) {
            add_edge (s,i+tot,1,0);
            rep (j,1,n) {
                add_edge (i+tot,mp[match[i][j]],1,f(i,match[i][j]));
            }
        }
        rep (i,1,tot) add_edge (i,t,1,0);
        rep (i,1,n) {
            spfa ();
            mcmf ();
            printf ("%lld",ans);
            printf ("%c",i==n?'
    ':' ');
        }
        return ;
    }
    
    int main () {
        int t;
        cin>>t;
        while (t--) {
            solve ();
        }
        return 0;
    }
    
  • 相关阅读:
    iOS开发进阶
    iOS开发UI篇—Quartz2D使用(绘图路径)
    iOS开发UI篇—控制器的View的创建
    iOS开发UI篇—Quartz2D简单使用(三)
    iOS开发从入门到精通
    win7访问win10需要用户名密码
    win10启用guest来宾账户的教程
    2021 年终总结
    vue elementui 树形
    js递归生成树形结构
  • 原文地址:https://www.cnblogs.com/hhlya/p/13559165.html
Copyright © 2020-2023  润新知