zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    The Dole Queue
    [ACM] 九度OJ 1553 时钟
    秘密:之所以不搞军事同盟,俄罗斯
    炮塔郝梦主solo
    男性在下一100层【第三层】——高仿手机银行client接口
    C# 它 抽象类和接口
    PO经批准的订单API
    XDU 1284 寻找礼物
    android JSON数据格式 解析
    select的种种取值
  • 原文地址:https://www.cnblogs.com/hhlya/p/13559165.html
Copyright © 2011-2022 走看看