zoukankan      html  css  js  c++  java
  • BZOJ 1061: [Noi2008]志愿者招募

    Time Limit: 20 Sec  Memory Limit: 162 MB

    Description

      申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管。布布刚上任就遇到了一个难
    题:为即将启动的奥运新项目招募一批短期志愿者。经过估算,这个项目需要N 天才能完成,其中第i 天至少需要
    Ai 个人。 布布通过了解得知,一共有M 类志愿者可以招募。其中第i 类可以从第Si 天工作到第Ti 天,招募费用
    是每人Ci 元。新官上任三把火,为了出色地完成自己的工作,布布希望用尽量少的费用招募足够的志愿者,但这
    并不是他的特长!于是布布找到了你,希望你帮他设计一种最优的招募方案。

    Input

      第一行包含两个整数N, M,表示完成项目的天数和可以招募的志愿者的种类。 接下来的一行中包含N 个非负
    整数,表示每天至少需要的志愿者人数。 接下来的M 行中每行包含三个整数Si, Ti, Ci,含义如上文所述。为了
    方便起见,我们可以认为每类志愿者的数量都是无限多的。

    Output

      仅包含一个整数,表示你所设计的最优方案的总费用。

    Sample Input

    3 3
    2 3 4
    1 2 2
    2 3 5
    3 3 2

    Sample Output

    14

    HINT

    1 ≤ N ≤ 1000,1 ≤ M ≤ 10000,题目中其他所涉及的数据均 不超过2^31-1。

    Source

    首先我们将问题转化,一开始有INF个志愿者,而每天对于志愿者数有一个需要补充的量,我们把它看做对于最大流量为INF,而i和i+1的边为INF减去所需志愿者的量。

    之后我们在建m条边,从l到r+1,流量INF,费用为输入的费用,表示我每使用一个志愿者补充流量就会产生对应的费用。

    然后EK即可。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    typedef long long ll;
    const int INF=2147483647,N=1005;;
    struct X
    {
        int v,cap,flow,cos,f,n;
    }x[N*30];
    int pre[N],fl[N],s=1,n;
    ll dis[N],ans;
    queue<int>q;
    bool vis[N];
    void add(int u,int v,int cap,int cos)
    {
        x[++s].n=x[u].f;
        x[x[u].f=s].v=v;
        x[s].cap=cap;
        x[s].cos=cos;
    }
    bool spfa()
    {
        memset(dis,0x3f,sizeof(dis));
        memset(fl,0,sizeof(fl));
        q.push(dis[0]=0);
        fl[0]=INF;
        for(;!q.empty();q.pop())
        {
            int u=q.front();
            for(int i=x[u].f;i;i=x[i].n)
                if(x[i].flow<x[i].cap&&dis[x[i].v]>dis[u]+x[i].cos)
                {
                    dis[x[i].v]=dis[u]+x[i].cos;
                    fl[x[i].v]=min(fl[u],x[i].cap-x[i].flow);
                    pre[x[i].v]=i;
                    if(!vis[x[i].v])
                    {
                        vis[x[i].v]=1;
                        q.push(x[i].v);
                    }
                }
            vis[u]=0;
        }
        return dis[n+1]<1000000;
    }
    int main()
    {
        int m;
        scanf("%d%d",&n,&m);
        add(0,1,INF,0);
        add(1,0,0,0);
        for(int i=1;i<=n;++i)
        {
            int a;
            scanf("%d",&a);
            add(i,i+1,INF-a,0);
            add(i+1,i,0,0);
        }
        while(m--)
        {
            int u,v,cos;
            scanf("%d%d%d",&u,&v,&cos);
            add(u,v+1,INF,cos);
            add(v+1,u,0,-cos);
        }
        while(spfa())
        {
            ans+=dis[n+1]*fl[n+1];
            for(int i=n+1;i;i=x[pre[i]^1].v)
            {
                x[pre[i]].flow+=fl[n+1];
                x[pre[i]^1].flow-=fl[n+1];
            }
        }
        printf("%lld",ans);
        return 0;
    }
  • 相关阅读:
    LA 2038 Strategic game(最小点覆盖,树形dp,二分匹配)
    UVA 10564 Paths through the Hourglass(背包)
    Codeforces Round #323 (Div. 2) D 582B Once Again...(快速幂)
    UVALive 3530 Martian Mining(贪心,dp)
    UVALive 4727 Jump(约瑟夫环,递推)
    UVALive 4731 Cellular Network(贪心,dp)
    UVA Mega Man's Mission(状压dp)
    Aizu 2456 Usoperanto (贪心)
    UVA 11404 Plalidromic Subsquence (回文子序列,LCS)
    Aizu 2304 Reverse Roads(无向流)
  • 原文地址:https://www.cnblogs.com/bzmd/p/6343667.html
Copyright © 2011-2022 走看看