zoukankan      html  css  js  c++  java
  • 网络流24题-汽车加油行驶问题

    题面

    首先忽略掉题中k的限制(油量的限制);

    那么很清楚的发现:对于一个点(i,j);向(i+1,j),(i,j+1)建立一条容1费0的边;向(i-1,j),(i,j-1)建立一条容1费B的边;

    很清楚的:从(1,1)到(n,n)跑费用流就好了;

    那么加上k的限制呢?

    由于k很小,所以我们可以建立分层图(分k+1层);

    第0层表示剩余油量是k,第k层表示剩余油量是0;

    那么当此处没有加油站时,我们要把第i层(0<=i<K)连向第i+1层的下一个位置,第k层则直接向第1层同一位置连上一条容1费A+C的边;

    当此处有加油站时,我们从第1层到第k层都向第0层连上一个容1费A的边,然后第0层再向别的点连边;

    然后原点是(1,1); 所有层的(n,n)向汇点连一条容1费0的边,跑费用流;

    我们注意到,所有边的容量都是1,那么便不用跑最小费用最大流,一边SPFA/Dijkstra就可以了(可以双端队列优化);

    #include <bits/stdc++.h>
    #define inc(i,a,b) for(register int i=a;i<=b;i++)
    using namespace std;
    class littlestar{
    	public:
    		int to;
    		int nxt;
    		int w;
    		void add(int u,int v,int gg);
    }star[2000010];
    int head[2000010],cnt;
    inline void littlestar::add(int u,int v,int gg)
    {
    	to=v;
    	nxt=head[u];
    	w=gg;
    	head[u]=cnt;
    }
    int n,k,A,B,C,tot;
    int query[101][101],a[101][101];
    int S,T;
    deque<int> q;
    int dis[1000010],vis[1000010];
    void SPFA()
    {
    	memset(dis,0x3f,sizeof(dis));
    	q.push_back(S);
    	dis[S]=0;
    	while(q.size()){
    		int u=q.front();
    		q.pop_front();
    		vis[u]=0;
    		for(register int i=head[u];i;i=star[i].nxt){
    			int v=star[i].to;
    			if(dis[v]>dis[u]+star[i].w){
    				dis[v]=dis[u]+star[i].w;
    				if(vis[v]==0){
    					vis[v]=1;
    					if(q.size()&&dis[v]>dis[q.front()]) q.push_back(v);
    					else q.push_front(v);
    				}
    			}
    		}
    	}
    }
    int main()
    {
    	cin>>n>>k>>A>>B>>C;
    	inc(i,1,n) inc(j,1,n){
    		scanf("%d",&a[i][j]);
    		++tot;
    		query[i][j]=tot;
    	}
    	S=tot*(k+1)+1,T=tot*(k+1)+2;
    	star[++cnt].add(S,1,0);
    	inc(i,1,n){
    		inc(j,1,n){
    			int tmp=query[i][j];
    			if(a[i][j]){
    				inc(o,1,k){
    					star[++cnt].add(o*tot+tmp,tmp,A);
    				}
    			}			
    			inc(o,0,k-1){
    				if(a[i][j]&&o) break;
    				if(i>1) star[++cnt].add(o*tot+tmp,(o+1)*tot+query[i-1][j],B);
    				if(j>1) star[++cnt].add(o*tot+tmp,(o+1)*tot+query[i][j-1],B);
    				if(i+1<=n) star[++cnt].add(o*tot+tmp,(o+1)*tot+query[i+1][j],0);
    				if(j+1<=n) star[++cnt].add(o*tot+tmp,(o+1)*tot+query[i][j+1],0);
    			}
    			star[++cnt].add(k*tot+tmp,tmp,A+C);
    		}
    	}
    	inc(i,0,k){
    		star[++cnt].add(i*tot+query[n][n],T,0);
    	}
    	SPFA();
    	cout<<dis[T];
    }
    
  • 相关阅读:
    tcp_wrapper
    iptables
    Openstack_后端存储平台Ceph
    Openstack_O版(otaka)部署_Horizon部署
    Openstack_O版(otaka)部署_网络服务Neutron部署
    Openstack_O版(otaka)部署_Nova部署
    Openstack_O版(otaka)部署_镜像服务glance部署
    Openstack_O版(otaka)部署_认证服务keystone部署
    Openstack_O版(otaka)部署_准备环境和依赖软件
    模块
  • 原文地址:https://www.cnblogs.com/kamimxr/p/11647121.html
Copyright © 2011-2022 走看看