[笔记] 网络流-最大流 POJ-1273\HDU-4240

本文介绍了最大流问题的基本概念,并详细阐述了Ford-Fulkerson算法及其在POJ-1273问题上的应用。接着,文章针对HDU-4240问题,对比了使用DFS和BFS搜索增广路的性能,并最终采用BFS提高了算法效率。文章涵盖了最大流问题的理论背景、算法原理以及实际问题的解决策略。

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

[1] POJ-1273

题目:http://poj.org/problem?id=1273

最直接的最大流问题,用了Ford-Fulkerson方法,DFS随机搜索增广路.

算法原理参考:http://blog.youkuaiyun.com/smartxxyx/article/details/9293665

/***********************
*  POJ-1273
*  Ford-Fulkerson
***********************/
#include <stdio.h>
#include <string.h>

const int INF = (1<<31)-1;
int map[500][500];//邻接矩阵 
int fa[500];//记录父节点 
int vis[500];//DFS标记数组 

int dfs(int stap,int min);

int n,m;
int main(){
    
    while (scanf("%d%d",&m,&n)!=EOF){
        
        memset(map,0,sizeof(map));
        for (int i=1;i<=m;i++){
            int u,v,val;
            scanf("%d%d%d",&u,&v,&val);
            map[u][v] += val;//累加处理,防止重边 
        }
        
        int max_flow = 0;
        int temp;
        
        while (1){
            
            memset(vis,0,sizeof(vis));
            vis[1] = 1;
            for (int i=1;i<=n;i++) fa[i] = i;
            
            temp = dfs(1,INF);//从顶点[1]出发,在残留网络中DFS搜索一条增广路,返回路径的合法流量 
            if (temp == INF) break;//如果搜不到增广路则说明已经没有更大流量
            max_flow += temp;
            
            //更新残留网络,正向边减去temp,反向边加上temp 
            int p = n;
            while (p!=1){
                int fat = fa[p];
                map[fat][p] -= temp;
                map[p][fat] += temp;
                p = fat;
            }
            
        }
        printf("%d\n",max_flow);
    }
    return 0;
}

int dfs(int stap,int min){
    
    for (int i=1;i<=n;i++)//寻找stap所指向的一个子节点 
    if (!vis[i]&&map[stap][i]>0){
        
        vis[i] = 1;
        fa[i] = stap;
        
        if (map[stap][i]<min) min = map[stap][i];//保持流量合法 
        if (i==n) return min;//DFS出口 
        else{
            int temp = dfs(i,min);
            if (temp<min) min = temp;
        }
    }
    
    if (fa[n]!=n) return min;//fa[n]!=n 说明本次搜素成功地找到一条增广路 
    else return INF;
}

[2] HDU-4240

题目:http://acm.hdu.edu.cn/showproblem.php?pid=4240

题意是求一个比值,[最大流]和[最大流量路径的流量]的比值.

本题用DFS找增广路时超时了,改用了BFS搜索增广路,但是时间效率仍然不高.

其实对算法的详细机制还没有很清楚,也还不清楚为什么BFS会比DFS快,慢慢体会

更高效的算法有DINIC和SAP等.

为了方便同时用了两个矩阵和邻接表

#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
const int INF = (1<<31)-1;
const int MAX = 1001;
int map[MAX][MAX];//记录残留网络
int org[MAX][MAX];//记录原图
int head[MAX];
int next[MAX*2];
int edge[MAX*2];
int fa[MAX];
int vis[MAX];//vis数组同时用作标记和记录源点到本节点的合法流量

int main(){
    
    int n,m,sta,end;
    int t,cases;
    scanf("%d",&t);
    while (t--){
        
        int u,v,val;
        scanf("%d%d%d%d%d",&cases,&n,&m,&sta,&end);
        sta++;end++;
        memset(map,0,sizeof(map));
        memset(org,0,sizeof(org));
        memset(head,0xff,sizeof(head));
        int cnt = 0;
        
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&u,&v,&val);
            map[u+1][v+1] += val;
            org[u+1][v+1] += val;
            
            cnt++;
            edge[cnt] = v+1;
            next[cnt] = head[u+1];
            head[u+1] = cnt;
            
            cnt++;
            edge[cnt] = u+1;
            next[cnt] = head[v+1];
            head[v+1] = cnt;
        }
        
        int max_flow = 0;
        int max_rot = 0;
        
        while (1){
            
            for (int i=1;i<=n;i++) fa[i] = i;
            memset(vis,0,sizeof(vis));
            vis[sta] = INF;
            queue<int> q;
            q.push(sta);

            while (!q.empty()){
                u = q.front();
                q.pop();

                for (int i=head[u];i!=-1;i=next[i]){
                    v = edge[i];
                    if (!vis[v]&&map[u][v]){
                        q.push(v);
                        fa[v] = u;
                        vis[v] = vis[u]<map[u][v] ? vis[u]:map[u][v];
                        if (v==end) break;
                    }
                }
                if (v==end) break;
            }
            
            if (vis[end]==0) break;
            max_flow += vis[end];
            int p = end;
            int rot_min = INF;
            while (p!=sta){
                int fat = fa[p];
                if (org[fat][p]<rot_min) rot_min = org[fat][p];
                map[fat][p] -= vis[end];
                map[p][fat] += vis[end];
                p = fat;
            }
            
            if (rot_min>max_rot) max_rot = rot_min;
        }
        
        double ans = ((double)max_flow)/((double)max_rot);
        printf("%d %.3lf\n",cases,ans);
        
    }
    
    return 0;
}

还是优快云上看代码舒服.
资源下载链接为: 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、付费专栏及课程。

余额充值