• P4009 汽车加油行驶问题 费用流


    题意:

    题解:

    • 如果无限油的话就是裸的分层图
    • 最多有k滴油  那么可以建立分层图  每一滴油建立一层即可
    • 然后按照题意模拟
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=500000+10,M=5e6+10;
    ll maxflow,mincost;
    int last[N],pre[N],dis[N],flow[N];
    bool vis[N];
    struct Edge{int next,to,flow,dis;}edge[M<<1];
    int pos=1,head[N];
    void init(){pos=1;memset(head,0,sizeof head);mincost=maxflow=0;}
    queue <int> q;
    void add(int from,int to,int flow,int dis)//flow流量 dis费用
    {
        edge[++pos].next=head[from];edge[pos].flow=flow;edge[pos].dis=dis;edge[pos].to=to;head[from]=pos;
        edge[++pos].next=head[to];edge[pos].flow=0;edge[pos].dis=-dis;edge[pos].to=from;head[to]=pos;
    }
    bool spfa(int s,int t)
    {
        memset(dis,0x3f,sizeof dis);
        memset(flow,0x3f,sizeof flow);
        memset(vis,0,sizeof vis);
        while (!q.empty()) q.pop();
        dis[s]=0; pre[t]=-1; q.push(s); vis[s]=1;
        int tot=0;
        while (!q.empty())
        {
            int now=q.front(); q.pop(); vis[now]=0;
            for (int i=head[now]; i; i=edge[i].next)
            {
                int to=edge[i].to;
                if  (edge[i].flow>0 && dis[to]>dis[now]+edge[i].dis)
                {
                    dis[to]=edge[i].dis+dis[now];
                    flow[to]=min(edge[i].flow,flow[now]);
                    last[to]=i;
                    pre[to]=now;
                    if (!vis[to])
                    {
                        q.push(to); vis[to]=1;
                    }
                }
            }
        }
        return pre[t]!=-1;
    }
    void MCMF(int s,int t)
    {
        while (spfa(s,t))
        {
            int now=t;
            maxflow+=flow[t];
            mincost+=flow[t]*dis[t];
            while (now!=s)
            {
                edge[last[now]].flow-=flow[t];//dis . flow
                edge[last[now]^1].flow+=flow[t];
                now=pre[now];
            }
        }
    }
    int n,m,A,B,C,K,s,t;
    int id(int x,int y){return (x-1)*n+y;}
    
    int main()
    {
        cin>>n>>K>>A>>B>>C;
        int T=n*n;
        s=(K+2)*T;t=s+1;
        add(s,id(1,1)+K*T,1,0);
        for(int i=0;i<=K;i++)
            add(id(n,n)+T*i,t,1,0);
        int x;
        for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)
        {
            scanf("%d",&x);
            if(x==1)
            {
                for(int s=0;s<K;s++)add(id(i,j)+s*T,id(i,j)+K*T,1,A);
                if(i+1<=n)add(id(i,j)+K*T,id(i+1,j)+(K-1)*T,1,0);
                if(j+1<=n)add(id(i,j)+K*T,id(i,j+1)+(K-1)*T,1,0);
                if(i-1>=1)add(id(i,j)+K*T,id(i-1,j)+(K-1)*T,1,B);
                if(j-1>=1)add(id(i,j)+K*T,id(i,j-1)+(K-1)*T,1,B);
                continue;
            }
            for(int s=1;s<=K;s++)
            {
                if(i+1<=n)add(id(i,j)+s*T,id(i+1,j)+(s-1)*T,1,0);
                if(j+1<=n)add(id(i,j)+s*T,id(i,j+1)+(s-1)*T,1,0);
                if(i-1>=1)add(id(i,j)+s*T,id(i-1,j)+(s-1)*T,1,B);
                if(j-1>=1)add(id(i,j)+s*T,id(i,j-1)+(s-1)*T,1,B);
            }
            add(id(i,j),id(i,j)+T*K,1,A+C);
        }
        MCMF(s,t);
        cout<<mincost;
    }
    View Code
  • 相关阅读:
    HTTP请求方法 GET POST【总结】
    Data Binding MVVM 数据绑定 总结
    Butter Knife 黄油刀
    原生JS强大DOM选择器querySelector与querySelectorAll
    JS日期Date详解与实例扩展
    JS中的冒泡排序以及实现一个数组中得最到最大的数字小例
    jquery.roundabout.js实现3D图片层叠旋转木马切换
    AngularJS 表格
    AngularJS XMLHttpRequest
    AngularJS Filters
  • 原文地址:https://www.cnblogs.com/bxd123/p/11740590.html
Copyright © 2020-2023  润新知