• 【最大流】【费用流】bzoj1834 [ZJOI2010]network 网络扩容


    引用题解:

    最大流+费用流。
    第一问最大流即可。
    第二问为“最小费用最大流”。
    由题意,这一问的可转化为在上一问的“残量网络”上,扩大一些边的容量,使能从新的图中的最大流为k。
    那么易得:对于还有剩余流量的边,走过他们的费用为0。而“增加流量”可变为:对残留网络上的每一条边建一条容量是∞费用是w的边。这表示从这些边走,每一流量的费用为w,这就符合题意了。
    最后建一个超级源点,从超级源向1建一条容量为k,费用为0的边,就可进行最小费用最大流算法
     
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    using namespace std;
    #define MAXN 1011
    #define MAXM 25001
    #define INF 2147483647
    int S,T,n,m,A[5001],B[5001],W1,Goal;
    int en,u[MAXM],W2[5001],v[MAXM],first[MAXN],next[MAXM],cap[MAXM],cost[MAXM];//Next Array
    bool inq[MAXN];
    int d[MAXN]/*spfa*/,p[MAXN]/*spfa*/,a[MAXN]/*可改进量*/;
    queue<int>q;
    void Init_MCMF(){memset(first,-1,sizeof(first));en=0;S=1;T=n;}
    void AddEdge(const int &U,const int &V,const int &W,const int &C)
    {u[en]=U; v[en]=V; cap[en]=W; cost[en]=C; next[en]=first[U]; first[U]=en++;
    u[en]=V; v[en]=U; cost[en]=-C; next[en]=first[V]; first[V]=en++;}
    bool Spfa(int &Flow,int &Cost)
    {
        memset(d,0x7f,sizeof(d));
        memset(inq,0,sizeof(inq));
        d[S]=0; inq[S]=1; p[S]=0; a[S]=INF; q.push(S);
        while(!q.empty())
          {
            int U=q.front(); q.pop(); inq[U]=0;
            for(int i=first[U];i!=-1;i=next[i])
              if(cap[i] && d[v[i]]>d[U]+cost[i])
                {
                  d[v[i]]=d[U]+cost[i];
                  p[v[i]]=i;
                  a[v[i]]=min(a[U],cap[i]);
                  if(!inq[v[i]]) {q.push(v[i]); inq[v[i]]=1;}
                }
          }
        if(d[T]>2100000000) return 0;
        Flow+=a[T]; Cost+=d[T]*a[T]; int U=T;
        while(U!=S)
          {
            cap[p[U]]-=a[T]; cap[p[U]^1]+=a[T];
            U=u[p[U]];
          }
        return 1;
    }
    int Flow,Cost;
    int Mincost()
    {
        Flow=0,Cost=0;
        while(Spfa(Flow,Cost));
    }
    int main()
    {
    	scanf("%d%d%d",&n,&m,&Goal);
    	Init_MCMF();
    	for(int i=1;i<=m;++i)
    	  {
    	  	scanf("%d%d%d%d",&A[i],&B[i],&W1,&W2[i]);
    	  	AddEdge(A[i],B[i],W1,0);
    	  }
    	Mincost(); printf("%d ",Flow);
    	for(int i=1;i<=m;++i) AddEdge(A[i],B[i],INF,W2[i]);
    	S=0; AddEdge(S,1,Goal,0);
    	Mincost(); printf("%d
    ",Cost);
    	return 0;
    }
    

      

  • 相关阅读:
    css3:让IE兼容background-size的方法
    判断浏览器版本是否是ie9以下浏览器,提示升级
    正则表达式
    H5页面内容较少时如何让页面全屏在手机显示呢
    页面滚动指定高度时添加样式或动画
    使用js实现导航切换效果变化(收集案例)
    单行文字定时滚动(收集案例)
    使用zepto.js完成的手机相册
    Repaint 、Reflow 的基本认识和优化
    Web-[强网杯 2019]随便注
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/4174457.html
Copyright © 2020-2023  润新知