• 网络流强化-POJ2516


      k种货物分开求解最小费用最大流,主要减少了寻找最短路的时间。

      

    #include<queue>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    #define maxe 256000   //pay
    #define maxv 5120    //pay
    #define maxn 55    //pay
    #define sc scanf
    #define pt printf
    #define rep(i,a,b)  for(int i=(a);i<(b);++i)
    const int inf = 0x3f3f3f3f; 
    int fee,cg,sp,need;
    int N,M,K ,s,t;
    typedef struct ed{
        int v,nxt,cap,dis;
    }ed;
    ed e[maxe];
    int nxt[maxe],tot,head[maxv],vis[maxv],d[maxv],bk[maxv];
    int mp[maxn][maxn][maxn];
    int mi(int a,int b) {return a<b?a:b;}
    void add(int u,int v,int cap,int dis)
    {
        e[tot].v=v;         e[tot].nxt=head[u];
        e[tot].dis=dis;     e[tot].cap=cap;
        head[u]=tot++;
    
        e[tot].v=u;         e[tot].nxt=head[v];
        e[tot].dis=-dis;    e[tot].cap=0;
        head[v]=tot++;
    } 
    int spfa()
    {
        queue<int> q;
        int u = s,v;
        q.push(u);
        while(!q.empty())
        {
            u = q.front(); q.pop();
            vis[u] = 0;
            for(int i = head[u];~i;i=e[i].nxt)
            {
                if(e[i].cap<1) continue;
                v = e[i].v;
                if(d[u]+e[i].dis<d[v])
                {
                    bk[v]=i;
                    d[v] = d[u]+e[i].dis;
                    if(vis[v]==0)
                    {
                        q.push(v);
                        vis[v]=1;
                    }
                }
            }
        }
        return d[t]!=inf;
    }
    
    void init()
    {
        tot=0;
        memset(head,-1,sizeof(head));   //pay 
    }
    int cust_need[maxn][maxn];
    int halt_prov[maxn][maxn];
    //第一次改进:如果仓库这种东西的存量为0或者客户需求为0,他们之间不建立边 —— 居然RE了
    int main()
    {
        freopen("in.txt","r",stdin);
        d[0]=0; bk[0]=-1;
        while(1)
        {
            need = fee = sp = 0;
            sc("%d%d%d",&N,&M,&K); //pt("%d %d %d
    ",N,M,K);
            if(N==0&&M==0&&K==0) break;
            s=0,t=1+N+M;
            int i,j,k;
            memset(mp,-1,sizeof(mp));
            for(i=0;i<N;++i)  for(j=1;j<=K;++j) sc("%d",&cust_need[i][j]),need+=cust_need[i][j];
            for(i=0;i<M;++i)  for(j=1;j<=K;++j) sc("%d",&halt_prov[i][j]);
            for(k=1;k<=K;++k)  for(i=0;i<N;++i) for(j=0;j<M;++j)
            {
                sc("%d",&mp[k][i][j]);
                if(halt_prov[j][k]==0||cust_need[i][k]==0) continue;
                add(j*K+k,K*M+i*K+k,mi(halt_prov[j][k],cust_need[i][k]),mp[k][i][j]);
            }  
            for(k=1;k<=K;++k)
            {
                init();
                for(i=0;i<N;++i) if(cust_need[i][k]>0) add(1+M+i,t,cust_need[i][k],0);
                for(j=0;j<M;++j) if(halt_prov[j][k]>0) add(0,1+j,halt_prov[j][k],0);
                for(i=0;i<N;++i) for(j=0;j<M;++j)
                {
                    if(halt_prov[j][k]==0||cust_need[i][k]==0) continue;
                    add(1+j,1+M+i,mi(halt_prov[j][k],cust_need[i][k]),mp[k][i][j]);
                }
                while(1)
                {
                    for(i=1;i<=t;++i) d[i]=inf,vis[i]=0; 
                    if(spfa()==0) break;
                    int min_flow = inf;
                    cg=bk[t];
                    while(cg!=-1)
                    {
                        min_flow = mi(min_flow,e[cg].cap);
                        cg=bk[e[cg^1].v];
                    }
                    sp+=min_flow;
                    cg=bk[t];
                    while(cg!=-1)
                    {
                        e[cg].cap-=min_flow;
                        e[cg^1].cap+=min_flow;
                        fee+=e[cg].dis*min_flow;
                        cg=bk[e[cg^1].v];
                    }
                }
            }
            if(sp==need)   pt("%d
    ",fee); //  write(fee), pt("
    ");
            else pt("-1
    ");    
        }
        
        return 0;
    }
    POJ 2516
  • 相关阅读:
    CSS技巧(二):CSS hack
    CSS技巧(一):清除浮动总洁
    js中apply方法的使用
    call 方法
    正则表达式
    【js事件详解】js事件封装函数,js跨浏览器事件处理机制
    [BZOJ 4300] 绝世好题
    [SPOJ1557] Can you answer these queries II
    [Codeforces 877E] Danil and a Part-time Job
    [Codeforces 914D] Bash and a Tough Math Puzzle
  • 原文地址:https://www.cnblogs.com/lighten-up-belief/p/11345934.html
Copyright © 2020-2023  润新知