zoukankan      html  css  js  c++  java
  • 费用流&网络流模版

    费用流模版:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<queue>
     4 using namespace std;
     5 
     6 const int Maxm=100000;//最大边数 
     7 const int Maxn=1000;//最大点数 
     8 struct Edge{
     9     Edge(){};
    10     Edge(int a,int b,int c,int d,int e){
    11         u=a;
    12         v=b; 
    13         f=c;
    14         w=d;
    15         nxt=e;
    16     }
    17     int u,v,f,w,nxt;//U当前点 V来自点 F最大流量 W费用 NXT下一个点 
    18 };
    19 int cnt=1;//边计数
    20 int inf=2147483647;//无限大 
    21 int g[Maxn+10];//点的边集的开始序号 
    22 Edge e[Maxm+10];//边集 
    23 int dist[Maxn+10];//费用 
    24 int src,sink;//源点与汇点 
    25 queue<int> que;//宽搜队列 
    26 bool inque[Maxn+10];//宽搜判断标志 
    27 int from[Maxn+10];//来源->用于计算费用 
    28 int ans=0;//存储最小费用 
    29 
    30 inline int remin(int a,int b){
    31     return a<b?a:b;
    32 }
    33 
    34 inline void insert(int u,int v,int f,int w){
    35     cnt++;
    36     e[cnt]=Edge(u,v,f,w,g[u]);
    37     g[u]=cnt;//增加一个边 
    38 } 
    39 
    40 inline void addEdge(int u,int v,int f,int w){
    41     insert(u,v,f,w);//插入正边 
    42     insert(v,u,0,-w);//插入反边 
    43 }
    44 
    45 inline bool spfa(){
    46     while (!que.empty()) que.pop();//清空队列 
    47     for (int i=0;i<=sink;i++) dist[i]=inf;//清最大值
    48     que.push(src);
    49     inque[src]=true;
    50     dist[src]=0;//加入源点
    51     //标准SPFA计算最短路 流量作为通行标准,费用作为路径长度 
    52     while(!que.empty()){
    53         int now=que.front();
    54         que.pop();
    55         for (int i=g[now];i;i=e[i].nxt){
    56             if (e[i].f!=0 && dist[e[i].v]>dist[now]+e[i].w){
    57                 dist[e[i].v]=dist[now]+e[i].w;
    58                 from[e[i].v]=i;
    59                 if (inque[e[i].v]==false){
    60                     inque[e[i].v]=true;
    61                     que.push(e[i].v);
    62                 }
    63             }
    64         }
    65         inque[now]=false;
    66     } 
    67     if (dist[sink]==inf) return false;//无法在增广 
    68     return true;
    69 }
    70 
    71 inline void calcAns(){
    72     int minflow=inf;
    73     for (int i=from[sink];i;i=from[e[i].u]) minflow=remin(minflow,e[i].f);//寻找整条路经的流量 
    74     for (int i=from[sink];i;i=from[e[i].u]) {
    75         e[i].f-=minflow;//正边减流量 
    76         e[i^1].f+=minflow;//反边加流量 
    77         ans+=e[i].w*minflow;//计算费用 
    78     }
    79 }
    80 
    81 inline void minCostFlow(){
    82     while(spfa())calcAns();
    83 }
    84 
    85 int main(){
    86     minCostFlow();
    87     return 0;
    88 }

    网络流模版:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<queue>
     4 using namespace std;
     5 
     6 const int Maxm=100000;//最大边数 
     7 const int Maxn=1000;//最大点数 
     8 struct Edge{
     9     Edge(){};
    10     Edge(int a,int b,int c,int d,int e){
    11         u=a;
    12         v=b; 
    13         f=c;
    14         w=d;
    15         nxt=e;
    16     }
    17     int u,v,f,w,nxt;//U当前点 V来自点 F最大流量 W费用 NXT下一个点 
    18 };
    19 int cnt=1;//边计数
    20 int inf=2147483647;//无限大 
    21 int g[Maxn+10];//点的边集的开始序号 
    22 Edge e[Maxm+10];//边集 
    23 int dist[Maxn+10];//费用 
    24 int src,sink;//源点与汇点 
    25 queue<int> que;//宽搜队列 
    26 bool inque[Maxn+10];//宽搜判断标志 
    27 int from[Maxn+10];//来源->用于计算费用 
    28 int ans=0;//存储最小费用 
    29 
    30 inline int remin(int a,int b){
    31     return a<b?a:b;
    32 }
    33 
    34 inline void insert(int u,int v,int f,int w){
    35     cnt++;
    36     e[cnt]=Edge(u,v,f,w,g[u]);
    37     g[u]=cnt;//增加一个边 
    38 } 
    39 
    40 inline void addEdge(int u,int v,int f,int w){
    41     insert(u,v,f,w);//插入正边 
    42     insert(v,u,0,-w);//插入反边 
    43 }
    44 
    45 inline bool spfa(){
    46     while (!que.empty()) que.pop();//清空队列 
    47     for (int i=0;i<=sink;i++) dist[i]=inf;//清最大值
    48     que.push(src);
    49     inque[src]=true;
    50     dist[src]=0;//加入源点
    51     //标准SPFA计算最短路 流量作为通行标准,费用作为路径长度 
    52     while(!que.empty()){
    53         int now=que.front();
    54         que.pop();
    55         for (int i=g[now];i;i=e[i].nxt){
    56             if (e[i].f!=0 && dist[e[i].v]>dist[now]+e[i].w){
    57                 dist[e[i].v]=dist[now]+e[i].w;
    58                 from[e[i].v]=i;
    59                 if (inque[e[i].v]==false){
    60                     inque[e[i].v]=true;
    61                     que.push(e[i].v);
    62                 }
    63             }
    64         }
    65         inque[now]=false;
    66     } 
    67     if (dist[sink]==inf) return false;//无法在增广 
    68     return true;
    69 }
    70 
    71 inline void calcAns(){
    72     int minflow=inf;
    73     for (int i=from[sink];i;i=from[e[i].u]) minflow=remin(minflow,e[i].f);//寻找整条路经的流量 
    74     for (int i=from[sink];i;i=from[e[i].u]) {
    75         e[i].f-=minflow;//正边减流量 
    76         e[i^1].f+=minflow;//反边加流量 
    77         ans+=e[i].w*minflow;//计算费用 
    78     }
    79 }
    80 
    81 inline void minCostFlow(){
    82     while(spfa())calcAns();
    83 }
    84 
    85 int main(){
    86     minCostFlow();
    87     return 0;
    88 }
  • 相关阅读:
    Linux显示2015年日历表
    Linux显示系统日期
    Dialogs 对话框
    grid 属性
    VS2010 fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏 嵌入清单
    Perl Tk grid 布局
    Perl Tk pack布局示例
    Perl Tk grid布局管理器
    Perl DBI模块
    输入文本框模型
  • 原文地址:https://www.cnblogs.com/WNJXYK/p/4063966.html
Copyright © 2011-2022 走看看