Dinic算法学至大佬,学以致用【挂上相应的题目】

2023-11-19

这个巨佬讲的超级厉害,学起来很快,还有优化的说呢


Dinic算法(研究总结,网络流)

网络流是信息学竞赛中的常见类型,笔者刚学习了最大流Dinic算法,简单记录一下

网络流基本概念

什么是网络流

在一个有向图上选择一个源点,一个汇点,每一条边上都有一个流量上限(以下称为容量),即经过这条边的流量不能超过这个上界,同时,除源点和汇点外,所有点的入流和出流都相等,而源点只有流出的流,汇点只有汇入的流。这样的图叫做网络流

所谓网络或容量网络指的是一个连通的赋权有向图 D= (V、E、C) , 其中V 是该图的顶点集,E是有向边(即弧)集,C是弧上的容量。此外顶点集中包括一个起点和一个终点。网络上的流就是由起点流向终点的可行流,这是定义在网络上的非负函数,它一方面受到容量的限制,另一方面除去起点和终点以外,在所有中途点要求保持流入量和流出量是平衡的。(引自百度百科)

定义

我们定义:
源点:只有流出去的点
汇点:只有流进来的点
流量:一条边上流过的流量
容量:一条边上可供流过的最大流量
残量:一条边上的容量-流量

几个基本性质

基本性质一:

对于任何一条流,总有流量<=容量

这是很显然的

基本性质二

对于任何一个不是源点或汇点的点u,总有

∑p∈Ek[p][u]==∑q∈Ek[u][q](其中k[i][j]表示i到j的流量)∑p∈Ek[p][u]==∑q∈Ek[u][q](其中k[i][j]表示i到j的流量)

这个也很显然,即一个点(除源点和汇点)的入流和出流相等

基本性质三

对于任何一条有向边(u,v),总有

k[u][v]==−k[v][u]k[u][v]==−k[v][u]

这个看起来并不是很好理解,它的意思就是一条边的反边上的流是这条边的流的相反数,可以这么想,就是如果有k[u][v]的流从u流向v,也就相当于有-k[v][u]的流从v流向u。这条性质非常重要。

网络流最大流

网络流的最大流算法就是指的一个流量的方案使得网络中流量最大。

网络流最大流的求解

网络流的所有算法都是基于一种增广路的思想,下面首先简要的说一下增广路思想,其基本步骤如下:

1.找到一条从源点到汇点的路径,使得路径上任意一条边的残量>0(注意是小于而不是小于等于,这意味着这条边还可以分配流量),这条路径便称为增广路
2.找到这条路径上最小的F[u][v](我们设F[u][v]表示u->v这条边上的残量即剩余流量),下面记为flow
3.将这条路径上的每一条有向边u->v的残量减去flow,同时对于起反向边v->u的残量加上flow(为什么呢?我们下面再讲)
4.重复上述过程,直到找不出增广路,此时我们就找到了最大流

这个算法是基于增广路定理(Augmenting Path Theorem): 网络达到最大流当且仅当残留网络中没有增广路(由于笔者知识水平不高,暂且不会证明)

举个例子:
此处输入图片的描述

为什么要连反向边

我们知道,当我们在寻找增广路的时候,在前面找出的不一定是最优解,如果我们在减去残量网络中正向边的同时将相对应的反向边加上对应的值,我们就相当于可以反悔从这条边流过。
比如说我们现在选择从u流向v一些流量,但是我们后面发现,如果有另外的流量从p流向v,而原来u流过来的流量可以从u->q流走,这样就可以增加总流量,其效果就相当于p->v->u->q,用图表示就是:
此处输入图片的描述
图中的蓝色边就是我们首次增广时选择的流量方案,而实际上如果是橘色边的话情况会更优,那么我们可以在v->u之间连一条边容量为u->v减去的容量,那我们在增广p->v->u->q的时候就相当于走了v->u这条"边",而u->v的流量就与v->u的流量相抵消,就成了中间那幅图的样子了。
如果是v->u时的流量不能完全抵消u->v的,那就说明u还可以流一部分流量到v,再从v流出,这样也是允许的。

一个小技巧

虽然说我们已经想明白了为什么要加反向边,但反向边如何具体实现呢?笔者在学习网络流的时候在这里困扰了好久,现在简要的总结在这里。
首先讲一下邻接矩阵的做法,对于G[u][v],如果我们要对其反向边进行处理,直接修改G[v][u]即可。
但有时会出现u->v和v->u同时本来就有边的情况,一种方法是加入一个新点p,使u->v,而v->u变成v->p,p->u。
另一种方法就是使用邻接表,我们把边从0开始编号,每加入一条原图中的边u->v时,加入边v->u流量设为0,那么这时对于编号为i的边u->v,我们就可以知道i^1就是其反向边v->u。

朴素算法的低效之处

虽然说我们已经知道了增广路的实现,但是单纯地这样选择可能会陷入不好的境地,比如说这个经典的例子:
此处输入图片的描述
我们一眼可以看出最大流是999(s->v->t)+999(s->u->t),但如果程序采取了不恰当的增广策略:s->v->u->t
此处输入图片的描述
我们发现中间会加一条u->v的边
此处输入图片的描述
而下一次增广时:
此处输入图片的描述
若选择了s->u->v->t
此处输入图片的描述
然后就变成
此处输入图片的描述
这是个非常低效的过程,并且当图中的999变成更大的数时,这个劣势还会更加明显。
怎么办呢?
这时我们引入Dinic算法

Dinic算法

为了解决我们上面遇到的低效方法,Dinic算法引入了一个叫做分层图的概念。具体就是对于每一个点,我们根据从源点开始的bfs序列,为每一个点分配一个深度,然后我们进行若干遍dfs寻找增广路,每一次由u推出v必须保证v的深度必须是u的深度+1。下面给出代码
一些变量的定义

int s,t;//源点和汇点
int cnt;//边的数量,从0开始编号。
int Head[maxN];//每一个点最后一条边的编号
int Next[maxM];//指向对应点的前一条边
int V[maxM];//每一条边指向的点
int W[maxM];//每一条边的残量
int Depth[maxN];//分层图中标记深度

Dinic主过程:

int Dinic()
{
    int Ans=0;//记录最大流量
    while (bfs())
    {
        while (int d=dfs(s,inf))
            Ans+=d;
    }
    return Ans;
}

bfs分层图过程

bool bfs()
{
    queue<int> Q;//定义一个bfs寻找分层图时的队列
    while (!Q.empty())
        Q.pop();
    memset(Depth,0,sizeof(Depth));
    Depth[s]=1;//源点深度为1
    Q.push(s);
    do
    {
        int u=Q.front();
        Q.pop();
        for (int i=Head[u];i!=-1;i=Next[i])
            if ((W[i]>0)&&(Depth[V[i]]==0))//若该残量不为0,且V[i]还未分配深度,则给其分配深度并放入队列
            {
                Depth[V[i]]=Depth[u]+1;
                Q.push(V[i]);
            }
    }
    while (!Q.empty());
    if (Depth[t]==0)//当汇点的深度不存在时,说明不存在分层图,同时也说明不存在增广路
        return 0;
    return 1;
}

dfs寻找增广路过程

int dfs(int u,int dist)//u是当前节点,dist是当前流量
{
    if (u==t)//当已经到达汇点,直接返回
        return dist;
    for (int i=Head[u];i!=-1;i=Next[i])
    {
        if ((Depth[V[i]]==Depth[u]+1)&&(W[i]!=0))//注意这里要满足分层图和残量不为0两个条件
        {
            int di=dfs(V[i],min(dist,W[i]));//向下增广
            if (di>0)//若增广成功
            {
                W[i]-=di;//正向边减
                W[i^1]+=di;反向边加
                return di;//向上传递
            }
        }
    }
    return 0;//否则说明没有增广路,返回0
}

把上面的内容都封装到类中:

class Graph
{
private:
    int s,t;
    int cnt;
    int Head[maxN];
    int Next[maxM];
    int V[maxM];
    int W[maxM];
    int Depth[maxN];
public:
    int n;
    void init(int nn,int ss,int tt)//初始化
        {
            n=nn;
            s=ss;
            t=tt;
            cnt=-1;
            memset(Head,-1,sizeof(Head));
            memset(Next,-1,sizeof(Next));
            return;
        }
    void _Add(int u,int v,int w)
        {
            cnt++;
            Next[cnt]=Head[u];
            V[cnt]=v;
            W[cnt]=w;
            Head[u]=cnt;
        }
    void Add_Edge(int u,int v,int w)//加边,同时加正向和反向的
        {
            _Add(u,v,w);
            _Add(v,u,0);
        }
    int dfs(int u,int dist)
        {
            //cout<<"Dfs:"<<u<<' '<<dist<<endl;
            if (u==t)
                return dist;
            for (int i=Head[u];i!=-1;i=Next[i])
            {
                if ((Depth[V[i]]==Depth[u]+1)&&(W[i]!=0))
                {
                    int di=dfs(V[i],min(dist,W[i]));
                    if (di>0)
                    {
                        W[i]-=di;
                        W[i^1]+=di;
                        return di;
                    }
                }
            }
            return 0;
        }
    int bfs()
        {
            //cout<<"Bfs.begin:"<<endl;
            queue<int> Q;
            while (!Q.empty())
                Q.pop();
            memset(Depth,0,sizeof(Depth));
            Depth[s]=1;
            Q.push(s);
            do
            {
                int u=Q.front();
                //cout<<u<<endl;
                Q.pop();
                for (int i=Head[u];i!=-1;i=Next[i])
                {
                    if ((W[i]>0)&&(Depth[V[i]]==0))
                    {
                        Depth[V[i]]=Depth[u]+1;
                        Q.push(V[i]);
                    }
                }
            }
            while (!Q.empty());
            //cout<<"Bfs.end"<<endl;
            if (Depth[t]>0)
                return 1;
            return 0;
        }
    int Dinic()
        {
            int Ans=0;
            while (bfs())
            {
                while (int d=dfs(s,inf))
                    Ans+=d;
            }
            return Ans;
        }
};

Dinic算法的优化

Dinic算法还有优化,这个优化被称为当前弧优化,即每一次dfs增广时不从第一条边开始,而是用一个数组cur记录点u之前循环到了哪一条边,以此来加速
总代码如下,修改的地方已在代码中标出:

class Graph
{
private:
    int cnt;
    int Head[maxN];
    int Next[maxM];
    int W[maxM];
    int V[maxM];
    int Depth[maxN];
    int cur[maxN];//cur就是记录当前点u循环到了哪一条边
public:
    int s,t;
    void init()
        {
            cnt=-1;
            memset(Head,-1,sizeof(Head));
            memset(Next,-1,sizeof(Next));
        }
    void _Add(int u,int v,int w)
        {
            cnt++;
            Next[cnt]=Head[u];
            Head[u]=cnt;
            V[cnt]=v;
            W[cnt]=w;
        }
    void Add_Edge(int u,int v,int w)
        {
            _Add(u,v,w);
            _Add(v,u,0);
        }
    int dfs(int u,int flow)
        {
            if (u==t)
                return flow;
            for (int& i=cur[u];i!=-1;i=Next[i])//注意这里的&符号,这样i增加的同时也能改变cur[u]的值,达到记录当前弧的目的
            {
                if ((Depth[V[i]]==Depth[u]+1)&&(W[i]!=0))
                {
                    int di=dfs(V[i],min(flow,W[i]));
                    if (di>0)
                    {
                        W[i]-=di;
                        W[i^1]+=di;
                        return di;
                    }
                }
            }
            return 0;
        }
    int bfs()
        {
            queue<int> Q;
            while (!Q.empty())
                Q.pop();
            memset(Depth,0,sizeof(Depth));
            Depth[s]=1;
            Q.push(s);
            do
            {
                int u=Q.front();
                Q.pop();
                for (int i=Head[u];i!=-1;i=Next[i])
                    if ((Depth[V[i]]==0)&&(W[i]>0))
                    {
                        Depth[V[i]]=Depth[u]+1;
                        Q.push(V[i]);
                    }
            }
            while (!Q.empty());
            if (Depth[t]>0)
                return 1;
            return 0;
        }
    int Dinic()
        {
            int Ans=0;
            while (bfs())
            {
                for (int i=1;i<=n;i++)//每一次建立完分层图后都要把cur置为每一个点的第一条边 感谢@青衫白叙指出这里之前的一个疏漏
                    cur[i]=Head[i];
                while (int d=dfs(s,inf))
                {
                    Ans+=d;
                }
            }
            return Ans;
        }
};

 


后面我在学习的时候,慢慢的挂上相应的题目。(更新ing)

 

ACM Computer Factory 【POJ - 3436】【网络流Dinic】带题意的,方便做

有N个机器人,他们可以将P种零件加工成新的P种零件,对于需要的P种零件,需要满足这样的条件,0必须不存在、1必须存在、2无所谓系列。然后,就可以把这P种零件加工成新的P种零件,那么不就是这样的不断的建立边,把始末位置对应上去,然后每个点和自己建立一条边,用来限流,毕竟每个单位时刻上只能造出那么多的零件的说的嘛,然后就是去求最大流了,Dinic来写,bfs建立分层图,dfs去搜答案的同时进行正向边减对应值,反向边加上对应值来写。

 

Dining 【POJ - 3281】【网络流Dinic模板题】

  模板题,可以自己去解哦,最好不要看别人的博客,自己想。

 

A Plug for UNIX 【POJ - 1087】【网络流Dinic模板】

从源点给予每个插座一条值为1的边,然后再对所有的用电器,从其唯一指定的插座连出一条值为1的边,那么接下去就是转接口了,怎么处理转接口的问题呢?譬如说可以把A用B来代替,那么不就是从B连一条通往A的边即可?但是由于B也可以通过别的转换得到,所以我们转接口的权值设定为INF。

 

Minimum Cost 【POJ - 2516】【最大流最小费用模板题】

第一次接触最大流最小费用(很多人都会习惯性的说是最小费用最大流,但是我认为,这是在满足最大流情况下的最小费用,所以叫最大流最小费用会不会更好一些呢?)这里的算法用的是spfa()来写的,每次找的是最小费用的流量,直到找不到可以从源点流到汇点的流量的时候,我们就是可以直接停下来并且输出答案了。

  在这道题的解决方案:有N个商家它们需要货物源,还有M个货物供应商,N个商家需要K种物品,每种物品都有对应的需求量,M个商家每种物品都是对应的存货,然后再是K个N*M的矩阵表示了K个物品从供货商运送到商家的单位上的价钱,那么就是标准的最大流最小费用了,我们只需要建立这样的边,对于所有的供应商都与源点建立流的大小为拥有的个数的边、与商家建立无穷大的边并且边的代价是单位流的代价,然后再由商家出发到达汇点建立流大小为其需要的边,与汇点和源点建立的边的代价都是0。

 

Farm Tour 【POJ - 2135】【最大流最小费用】

  这道题的题意是我们需要跑一圈(不能经过相同的路径),问最小经历的权值是多少?既然跑一圈回来,不妨可以看成跑两次到终点呢,剩下自己考虑哦。

 

星际竞速 【HYSBZ - 1927】【最大流最小费用+建边思路】

  一道中文题,但是有点需要建边的思路,我们得考虑每个点只走一次,并且还要取到最优的方案。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Dinic算法学至大佬,学以致用【挂上相应的题目】 的相关文章

  • LeetCode-Python-1584. 连接所有点的最小费用(MST)

    给你一个points 数组 表示 2D 平面上的一些点 其中 points i xi yi 连接点 xi yi 和点 xj yj 的费用为它们之间的 曼哈顿距离 xi xj yi yj 其中 val 表示 val 的绝对值 请你返回将所有点
  • True Liars 【POJ - 1417】【种类并查集+0-1背包】

    题目链接 题目想要知道有P个好人 说真话的人 和Q个坏人 说假话的人 并且有N条信息 代表A说B是好人 yes 坏人 no 那么 在保证答案唯一的情况下输出这P个好人 并且最后的时候输出 end 否则 输出 no 坑点 答案唯一指的是最后你
  • UVA-1601 万圣节后的早晨 题解答案代码 算法竞赛入门经典第二版

    GitHub jzplp aoapc UVA Answer 算法竞赛入门经典 例题和习题答案 刘汝佳 第二版 以三个点的当前位置作为状态 广度优先遍历 找到终点即为最短次数 注意 一次可以移动多个点 但是每个点只能移动一步 在同一次中 B可
  • P1218 [USACO1.5]特殊的质数肋骨 Superprime Rib【普及】

    USACO1 5 特殊的质数肋骨 Superprime Rib 题目描述 农民约翰的母牛总是产生最好的肋骨 你能通过农民约翰和美国农业部标记在每根肋骨上的数字认出它们 农民约翰确定他卖给买方的是真正的质数肋骨 是因为从右边开始切下肋骨 每次
  • 无向图的遍历-BFS与DFS

    一 理论部分 无向图的遍历可用深度搜索 DFS 与广度搜索 BFS 深度搜索的基本方式是由图的一个节点1出发然后随机选一个与其相邻的节点2 接着在选择一个与其相邻的节点3 当一条路遍历完后再选择最近一个遍历过的 且相邻节点有未遍历过的节点
  • PCL点云处理之批量读写点云、随机赋予颜色 并保存

    include
  • Financial Crisis【点双连通分量】

    题目链接 HDU 3749 你以为学了Tarjan会写几个边双就真的理解什么是双连通分量了吗 我原来真的不懂什么叫做点双BCC 不过这都没有关系 解决了这个问题之后 我终于知道了什么叫做点双连通分量了 这是一个绝对绝对经典的问题 首先讲一下
  • Even Degree【2020 年 “游族杯”E题】【欧拉回路】

    题目链接 题意 有N个点 M条边 每次可以删去一条两端点的度不都是奇数的边 问最多可以删除几条边 题目保证初始所有点度为偶数 首先 题目保证了初始的时候所有的点的度都是为偶数的 于是原图中的每一个联通块一定是一个欧拉回路 对于欧拉回路 最好
  • 离散数学第一章总结

    离散数学第一章 1 公式类型 1 重言式 也是永真式 公式真值恒为1 2 矛盾式 永假式 真值恒为0 3 可满足式 不是矛盾式的就都是可满足式 重言式一定是可满足式 2 成真赋值与成假赋值 也叫成真指派与成假指派 一组原子的取值 真值指派
  • Python,创建map

    import matplotlib pyplot as mpp import os random math matplotlib version 3 5 1 numpy version 1 21 5 创建画布及坐标轴 def set cav
  • 矩阵树定理

    启蒙 http zhengruioi com contest 1416 T1 T2的10分暴力 后面是论文科技 不搞了 https www luogu com cn problem P6178 O n 3
  • AcWing 378. 骑士放置(最大独立集&&匈牙利算法)

    输入样例 2 3 0 输出样例 4 解析 题意为求最大独立集 即为总点数 最小点覆盖 include
  • POJ 3259 Wormholes(最短路——Bellman-ford)

    A Wormholes While exploring his many farms Farmer John has discovered a number of amazing wormholes A wormhole is very p
  • Codeforces Round #751 (Div. 2) D. Frog Traveler(BFS)

    题解 因为我们最多把所有的点跳一遍么 所以直接BFS模拟一下就行了 注意现在跳的点不能是以前已经跳过的点 并且只能越跳越高 否则没有意义 这样就保证了时间复杂度是线性的 AC代码 include
  • Fix a Tree【Codeforces 699 D】【dfs + 树的性质】

    Codeforces Round 363 Div 2 D 题意 有N个点 每个点i都有一个父节点p i 如果 i p i 则是说明i结点是根结点 现在我们给出这样的1 N的p i 这可能是不合法的 问 我们应该最少改变多少个使它变成一棵合法
  • Summer Holiday HDU - 1827 强连通分量+缩点

    To see a World in a Grain of Sand And a Heaven in a Wild Flower Hold Infinity in the palm of your hand And Eternity in a
  • 【codeforces #290(div 1)】ABC题解

    A Fox And Names time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard o
  • 2023杭电暑假多校4 题解

    3 Simple Set Problem 题意 k 个多重集合 每个集合选出一个数形成新集合A 求 m a x A m
  • Dinic算法学至大佬,学以致用【挂上相应的题目】

    这个巨佬讲的超级厉害 学起来很快 还有优化的说呢 Dinic算法 研究总结 网络流 网络流是信息学竞赛中的常见类型 笔者刚学习了最大流Dinic算法 简单记录一下 网络流基本概念 什么是网络流 在一个有向图上选择一个源点 一个汇点 每一条边
  • BFS遍历树和DFS遍历树

    遍历树 按照遍历的顺序 如不清楚图的遍历 请先阅读图的遍历 绘制成树型结构 DFS遍历树 以下为图到遍历树的转化 如果不清楚图的遍历 请先阅读笔者的另一篇文章 图的遍历 动图 按照DFS遍历的顺序 绘制成一棵树 途中红色的边就是遍历过程中没

随机推荐

  • 再见,百度网盘!新 60MB/s!

    点击上方卡片 关注回复 青春网盘 即可获得下载链接 近些年 大家苦百度网盘久矣 非会员的限速导致下载速度大多停留再KB为单位 这个问题一直被人吐槽 有关部门规定网盘不许无底线限速 因此百度给出的整改措施是 推出百度网盘青春版 免费用户将享受
  • 【问答21】C语言:位域和字节序

    1 粉丝问题 自己编写的一个协议相关代码 位域的值解析和自己想象的有出入 结构体的头 解析代码和测试结果 就是说通过函数hexdump 解析出的内存是十六进制是 81 83 20 3B 从数据帧解析出的 opcode 0x8 该粉丝不明白为
  • SMB/CIFS--NetBOIS/Browser/NBNS 协议

    在NetBIOS出现之后 Microsoft就使用NetBIOS实现了 一个网络文件 打印服务系统 这个系统基于NetBIOS设定了一套文件共享协议 Microsoft称之为SMB Server Message Block 协议 这个协议被
  • Windows下编译FFmpeg详解

    Windows下编译FFmpeg 2 6 1详解 在诸多网友帮助下终于搞定了FFmpeg V2 6 1 由于编译环境和程序版本的不同 造成了很多不必要的时间浪费 特在此将编译过程和遇到的问题解决方法写出来 以便方便大家 编译环境 PC Wi
  • 文件操作中出现system.notsupportedexception异常

    偶然的用了如下代码 string sourceDoc lt 文件全路径 gt bool isExists File Exists sourceDoc 此时isExists变量得到的值为false 仔细查看了变量sourceDoc的值 确定路
  • springBoot:方法上配置produces = {"application/json;charset=UTF-8"} 参数

    方法上有 produces application json charset UTF 8 去掉方法上面的 produces application json charset UTF 8 之后 定义了返回格式
  • Django笔记

    文章目录 Django笔记 1 Django项目 2 学习笔记 3 仅供参考 第一天 1 项目环境搭建 1 1 cmd 创建项目虚拟环境和指定Django版本 1 2 pycharm 创建项目 虚拟环境文件夹
  • 分析系统 - 使用Python爬虫

    在竞争激烈的市场环境中 了解和分析竞争对手的销售策略和市场表现对于企业的成功至关重要 本文将介绍如何利用Python爬虫建立低成本的销售竞争对手分析系统 探索其方法 工具和好处 并同时解决可能出现的问题 销售竞争对手分析的目标是获取有关竞争
  • asoc widget path route(audio_map)

    上一篇文章中 我们介绍了音频驱动中对基本控制单元的封装 kcontrol 利用kcontrol 我们可以完成对音频系统中的mixer mux 音量控制 音效控制 以及各种开关量的控制 通过对各种kcontrol的控制 使得音频硬件能够按照我
  • 6_线性表的相关操作

    文章目录 线性表的一些常用操作 线性表操作的实现 用C语言描述线性表 小结 线性表的一些常用操作 创建线性表 销毁线性表 清空线性表 将元素插入线性表 将元素从线性表中删除 获取线性表中某个位置的元素 获取线性表的长度 线性表操作的实现 线
  • Ubuntu系统安装Nvidia显卡驱动、Cuda、Cudnn、Pytorch、Tensorflow

    如果你的机器显卡是集成显卡 或者是老旧版本 那么不支持GPU加速 只能使用CPU版本的Pytorch Tensorflow 本文的前提是你有一块好的Nvidia显卡 1 如何查看电脑的显卡型号 在windows系统上 查看显卡型号的方法如下
  • 【数据结构】【王道408】——PPT截图与思维导图

    自用视频PPT截图 视频网址王道B站链接 23考研 408新增考点 并查集 红黑树 2023年408真题数据结构篇 408考纲解读 考纲变化 目录 第一章 绪论 第二章 线性表 顺序表 单链表 双链表 循环链表 静态链表 差别 第三章 栈
  • python大一考试知识点_Python复习知识点总结(针对校招

    正文 Python是门动态语言 运行时候采取检查数据类型 Python解释器 让其他程序运行起来的程序 Python解释器读取程序 按照其中的语句顺序执行 并得出结果 做了什么 解释器将语句翻译成一组字节码指令 pyc 字节码运行速度比源代
  • 图片撕纸效果处理

  • 自动化办公神器!用Python批量识别发票并录入到Excel表格!可以讨财务女神开心了!

    故事的开始 今天去财务拿上个月的工资条核对 发现女神一脸闷闷不乐 好像天要塌下来一样 我对完工资就问 女神 你咋不开心 不是马上就要发工资了嘛 女神说 老板刚给我派了个任务 让我把上个月这个月的发票都做一个Excel表格 今天下班前给他 这
  • windows10下编译boost1.74

    系列文章目录 文章目录 系列文章目录 前言 一 准备 二 编译步骤 前言 最近公司的项目中用到boost1 74 我机器上已经编译了boost1 79 为了配合项目无奈只有重新编译boost1 74 一 准备 1 visual studio
  • VMware镜像文件下载

    VMware镜像文件下载 http blog sina com cn s blog 517c21c00102x5ja html 貌似Centos 6不能下载啊 其他的没有测试
  • 12个真实项目实战带你玩转Java并发编程

    这篇博客 我会总结如下内容 满满的干货 篇幅可能会很长 做好心理准备 Immutable Object 不可变对象模式 在不引入锁的条件下 能保证访问共享变量时是线程安全的 缺点是会频繁的创建变量 Guarded Suspension 保护
  • 什么是架构,架构的本质是什么

    不论是开发人员还是架构师 我们都一直在跟软件系统打交道 架构是在工作中出现最频繁的术语之一 那么 到底什么是架构 你可能有自己的答案 也有可能没有答案 对 架构 的理解需要我们不断在实践中思考 归纳 演绎 形成自己的认知 一 什么是软件架构
  • Dinic算法学至大佬,学以致用【挂上相应的题目】

    这个巨佬讲的超级厉害 学起来很快 还有优化的说呢 Dinic算法 研究总结 网络流 网络流是信息学竞赛中的常见类型 笔者刚学习了最大流Dinic算法 简单记录一下 网络流基本概念 什么是网络流 在一个有向图上选择一个源点 一个汇点 每一条边