网络流

本文详细介绍了最大流问题的几种经典算法实现,包括Edmonds-Karp算法、Shortest Augmenting Path (SAP)算法及最小费用最大流算法,并提供了完整的C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


EK求最大流。

#include <queue>
#include <stdio.h>
#include <string.h>

using namespace std;

#define N 205
#define M 405
#define INF 0x7fffffff

#define min(a,b) a < b ?  a : b
#define CLR(a,v) memset(a,v,sizeof(a))

struct Vertex
{
    int head;
}V[N];

struct Edge
{
    int v,c,f,next;
}E[M];

int pre[N],flow[N];

int top,s,t;

void Init()
{
    top = 0;
    CLR(V,-1);
}

void Add_edge(int u,int v,int c)
{
    E[top].v = v;
    E[top].c = c;
    E[top].f = 0;
    E[top].next = V[u].head;
    V[u].head = top++;
}

bool Ed_Karp()
{
    CLR(flow,0);
    queue<int> Q;
    Q.push(s);
    flow[s] = INF;
    while(!Q.empty())
    {
        int u = Q.front();
        for(int i=V[u].head;i!=-1;i=E[i].next)
        {
            int v = E[i].v;
            if(!flow[v] && E[i].c > E[i].f)
            {
                pre[v] = i;
                flow[v] = min(flow[u],E[i].c-E[i].f);		//flow[v] represents the min flow in the way from "s" to "v".
                if(v == t)
                    return true;
                Q.push(v);
            }
        }
        Q.pop();
    }
    return false;
}

int Ford_Fulkerson()
{
    int i,MaxFlow = 0;
    while(Ed_Karp())
    {
        for(int v=t;v!=s;v=E[i^1].v)
        {
            i = pre[v];
            E[i].f   += flow[t];
            E[i^1].f -= flow[t];        //cool
        }
        MaxFlow += flow[t];
    }
    return MaxFlow;
}

SAP求最大流。

#include <queue>
#include <stdio.h>
#include <string.h>

using namespace std;

#define N 205
#define M 405
#define INF 0x7fffffff

#define min(a,b) a < b ?  a : b
#define CLR(a,v) memset(a,v,sizeof(a))

struct Vertex
{
    int head;
}V[N];

struct Edge
{
    int v,c,f,next;
}E[M];

int d[N],pre[N],cur[N],gap[N];

int top,s,t,n;

void Init()
{
    top = 0;
    CLR(V,-1);
}

void Add_edge(int u,int v,int c)
{
    E[top].v = v;
    E[top].c = c;
    E[top].f = 0;
    E[top].next = V[u].head;
    V[u].head = top++;
}

void set_d()
{
    queue<int> Q;
    CLR(d,-1);
    CLR(gap,0);
    d[t] = 0;
    Q.push(t);
    while(!Q.empty())
    {
        int v = Q.front();
        Q.pop();
        ++gap[ d[v] ];
        for(int i=V[v].head;i!=-1;i=E[i].next)
        {
            int u = E[i].v;
            if(d[u] == -1)
            {
                d[u] = d[v]+1;
                Q.push(u);
            }
        }
    }
}

int Sap()
{
    set_d();    //You can replace it with "CLR(d,0)" if you feel it trouble
    int MaxFlow = 0, u = s;
    int flow = INF;
    memcpy(cur,V,sizeof(V));                        //current arc
    while(d[s] < n)
    {
        int &i = cur[u];                            //reference
        for(;i!=-1;i=E[i].next)
        {
            int v = E[i].v;
            if(E[i].c > E[i].f && d[u] == d[v]+1)  //admissible arc
            {
                u = v;
                pre[v] = i;
                flow = min(flow,E[i].c-E[i].f);
                if(u == t)
                {
                    while(u != s)
                    {
                        int j = pre[u];
                        E[j].f   += flow;
                        E[j^1].f -= flow;
                        u = E[j^1].v;
                    }
                    MaxFlow += flow;
                    flow = INF;
                }
                break;
            }
        }
        if(i == -1)    //there's no admissible arc.
        {
            if(--gap[ d[u] ] == 0)
                break;
            int dmin = n-1;
            cur[u] = V[u].head;
            for(int j=V[u].head;j!=-1;j=E[j].next)
                if(E[j].c > E[j].f)     //not full arc
                    dmin = min(dmin,d[ E[j].v ]);
            d[u] = dmin+1;
            ++gap[ d[u] ];
            if(u != s)
                u = E[ pre[u]^1 ].v;
        }
    }
    return MaxFlow;
}


最小费用最大流。(最小费用路算法)

需要注意的地方:加反向边时,费用为真实费用的负值。

#include <queue>
#include <stdio.h>
#include <string.h>

using namespace std;

#define N 105
#define M 5205
#define INF 0x3fffffff

#define min(a,b) a < b ?  a : b
#define CLR(a,v) memset(a,v,sizeof(a))

struct Vertex
{
    int head;
}V[N];

struct Edge
{
    int v,c,f,cost,next;
}E[M];

int pre[N],dis[N];

int top,s,t;

bool in[N];

void Init()
{
    top = 0;
    CLR(V,-1);
}

void Add_edge(int u,int v,int c,int cost)
{
    E[top].v = v;
    E[top].c = c;
    E[top].f = 0;
    E[top].cost = cost;
    E[top].next = V[u].head;
    V[u].head = top++;
}

bool Spfa()
{
    CLR(dis,63);
    CLR(in,false);
    queue<int> Q;
    Q.push(s);
    dis[s] = 0;
    in[s] = true;
    while(!Q.empty())
    {
        int u = Q.front();
        for(int i=V[u].head;i!=-1;i=E[i].next)
        {
            int v = E[i].v;
            if(dis[u]+E[i].cost < dis[v] && E[i].c > E[i].f)
            {
                dis[v] = dis[u]+E[i].cost;
                pre[v] = i;
                if(!in[v])
                    Q.push(v);
                in[v] = true;
            }
        }
        Q.pop();
        in[u] = false;
    }
    return dis[t] != dis[N-1];
}

int Ford_Fulkerson()
{
    int i,MinCost = 0;
    while(Spfa())
    {
        int flow = INF;
        for(int v=t;v!=s;v=E[i^1].v)
        {
            i = pre[v];
            flow = min(flow,E[i].c-E[i].f);
        }
        for(int v=t;v!=s;v=E[i^1].v)
        {
            i = pre[v];
            E[i].f   += flow;
            E[i^1].f -= flow;
            MinCost += flow * E[i].cost;
        }
    }
    return MinCost;
}


资源下载链接为: https://pan.quark.cn/s/22ca96b7bd39 在 IT 领域,文档格式转换是常见需求,尤其在处理多种文件类型时。本文将聚焦于利用 Java 技术栈,尤其是 Apache POI 和 iTextPDF 库,实现 doc、xls(涵盖 Excel 2003 及 Excel 2007+)以及 txt、图片等格式文件向 PDF 的转换,并实现在线浏览功能。 先从 Apache POI 说起,它是一个强大的 Java 库,专注于处理 Microsoft Office 格式文件,比如 doc 和 xls。Apache POI 提供了 HSSF 和 XSSF 两个 API,其中 HSSF 用于读写老版本的 BIFF8 格式(Excel 97-2003),XSSF 则针对新的 XML 格式(Excel 2007+)。这两个 API 均具备读取和写入工作表、单元格、公式、样式等功能。读取 Excel 文件时,可通过创建 HSSFWorkbook 或 XSSFWorkbook 对象来打开相应格式的文件,进而遍历工作簿中的每个 Sheet,获取行和列数据。写入 Excel 文件时,创建新的 Workbook 对象,添加 Sheet、Row 和 Cell,即可构建新 Excel 文件。 再看 iTextPDF,它是一个用于生成和修改 PDF 文档的 Java 库,拥有丰富的 API。创建 PDF 文档时,借助 Document 对象,可定义页面尺寸、边距等属性来定制 PDF 外观。添加内容方面,可使用 Paragraph、List、Table 等元素将文本、列表和表格加入 PDF,图片可通过 Image 类加载插入。iTextPDF 支持多种字体和样式,可设置文本颜色、大小、样式等。此外,iTextPDF 的 TextRenderer 类能将 HTML、
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值