• 「BZOJ1834」[ZJOI2010]网络扩容


    最大流费用流二合一

    注意跑费用流用的图要保留跑完最大流后的反向边

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 const int N=1010,M=5010,oo=2e9;
      4 int n,m,k,s,t;
      5 int level[N],edge_tot,edge_tot2;
      6 struct Edge{
      7     int from,to,flow,cap,w;
      8 }edge[M<<1],edge2[M<<2];
      9 vector<int>point[N],point2[N];
     10 void add_edge(int f,int t,int c,int ww){
     11     edge[edge_tot]=(Edge){f,t,0,c,ww};
     12     point[f].push_back(edge_tot++);
     13     return;
     14 }
     15 void add_edge2(int f,int t,int ff,int c,int ww){
     16     edge2[edge_tot2]=(Edge){f,t,ff,c,ww};
     17     point2[f].push_back(edge_tot2++);
     18     return;
     19 }
     20 bool bfs(){
     21     memset(level,0,sizeof(level));
     22     queue<int>q;
     23     q.push(s);
     24     level[s]=1;
     25     int x;
     26     while(!q.empty()){
     27         x=q.front();q.pop();
     28         for(int i=0;i<point[x].size();i++){
     29             Edge& e=edge[point[x][i]];
     30             if(e.cap<=e.flow||level[e.to]) continue;
     31             level[e.to]=level[e.from]+1;
     32             q.push(e.to);
     33         }
     34     }
     35     return level[t];
     36 }
     37 int dfs(int k,int a){
     38     if(!a||k==t) return a;
     39     int f,ans=0;
     40     for(int i=0;i<point[k].size();i++){
     41         Edge& e=edge[point[k][i]];
     42         if(e.cap<=e.flow||level[e.to]!=level[k]+1) continue;
     43         if(f=dfs(e.to,min(a,e.cap-e.flow))){
     44             a-=f,ans+=f;
     45             edge[point[k][i]].flow+=f;
     46             edge[point[k][i]^1].flow-=f;
     47             if(!a) return ans;
     48         }
     49     }
     50     return ans;
     51 }
     52 int dinic(){
     53     int ans=0;
     54     while(bfs()) 
     55         ans+=dfs(s,oo);
     56     return ans;
     57 }
     58 int dis[N],pre[N];
     59 bool inq[N];
     60 bool spfa(){
     61     queue<int>q;
     62     memset(dis,127/2,sizeof(dis));
     63     q.push(s);
     64     dis[s]=0,inq[s]=1;
     65     int x;
     66     while(!q.empty()){
     67         x=q.front();q.pop();
     68         inq[x]=0;
     69         for(int i=0;i<point2[x].size();i++){
     70             Edge& e=edge2[point2[x][i]];
     71             if(e.cap<=e.flow) continue;
     72             if(dis[e.to]>dis[x]+e.w){
     73                 dis[e.to]=dis[x]+e.w,pre[e.to]=point2[x][i];
     74                 if(!inq[e.to]){q.push(e.to);inq[e.to]=1;}
     75             }
     76         }
     77     }
     78     return dis[t]<=1e9;
     79 }
     80 int maxflowmincost(){
     81     int now,ans=0,f;
     82     while(spfa()){
     83         now=t,f=oo;
     84         while(now!=s){
     85             f=min(f,edge2[pre[now]].cap-edge2[pre[now]].flow);
     86             now=edge2[pre[now]].from;
     87         }
     88         ans+=f*dis[t],now=t;
     89         while(now!=s){
     90             edge2[pre[now]].flow+=f,edge2[pre[now]^1].flow-=f;
     91             now=edge2[pre[now]].from;
     92         }
     93     }
     94     return ans;
     95 }
     96 int main(){
     97     int t1,t2,t3,t4;
     98     scanf("%d%d%d",&n,&m,&k);
     99     for(int i=1;i<=m;i++){
    100         scanf("%d%d%d%d",&t1,&t2,&t3,&t4);
    101         add_edge(t1,t2,t3,t4);
    102         add_edge(t2,t1,0,-t4);
    103     }
    104     s=1,t=n;
    105     printf("%d ",dinic());
    106     s=n+1;
    107     add_edge2(s,1,0,k,0);add_edge2(1,s,0,0,0);
    108     for(int i=0;i<m;i++){
    109         Edge& e=edge[i<<1];
    110         if(e.cap>e.flow){
    111             add_edge2(e.from,e.to,e.flow,e.cap,0);
    112         }
    113         add_edge2(e.from,e.to,0,k,e.w);
    114         add_edge2(e.to,e.from,0,0,-e.w);
    115         e=edge[i<<1|1];
    116         add_edge2(e.from,e.to,e.flow,0,0);
    117     }
    118     printf("%d",maxflowmincost());
    119     return 0;
    120 }
  • 相关阅读:
    C#如何释放未托管资源
    C# 如何将一个List转换为只读的
    【转载】所谓爱情不是一个人的事情(爱情不完全手册)
    vbs SendKey 用法 Sendkey 键盘对应的码表
    PowerShell签名和执行策略
    IDisposable接口和析构函数的联合使用
    [读报]2009中国基金业明星基金奖揭晓
    【读书笔记】泛型接口 和 泛型方法
    C# 反射(转)
    设计模式详解——装饰者模式
  • 原文地址:https://www.cnblogs.com/mycups/p/8528107.html
Copyright © 2020-2023  润新知