这学期两门主课 算法设计与分析(Algorithm and Analysis,ADA) 图论与算法(Graph Theory and Algorithms, GTA) 都涉及到很多经典图论问题以及相关代码实现,遂写下此文,以记录学习过程,随缘更新。


深度优先遍历(经典DFS):

从图中某一个节点出发,如果有未探索的邻居节点,则选择其中应该进行深入探索(其他节点暂时不管),每到一个新的节点则递归进行上述过程。当探索无法继续时(当前节点的所有邻居都在前面的探索过程中被标记过),则沿原路径回退。回退到某个节点时,若它还有其他的邻居节点没有探索,则继续深入探索。

使用白色,黑色,灰色记录每个节点的状态:

白色:表示一个节点尚未被遍历;

灰色:表示一个节点已经被遍历到,但是对于它的遍历尚未结束;即该节点还有若干邻居节点等待遍历,而当前算法正在递归处理其中一个邻居节点;

黑色:表示一个节点的所有邻居已经完成遍历,其自身的遍历也结束。

框架代码(包括封装和实现两部分):

具体实现(根据DFS遍历顺序简单输出一下各个节点的编号):

// DFS
#include <iostream>
#define N 10000
using namespace std;int graph[N][N];
int color[N]; // 0 white, 1 grey, 2 black
int n, m;void dfs(int v)
{color[v] = 1;for (int i = 1; i <= n; i++){if (i != v && graph[v][i] == 1){if (color[i] == 0){dfs(i);}}}cout << v << " ";color[v] = 2;
}void my_dfs()
{for (int i = 1; i <= n; i++){if (color[i] == 0)dfs(i);}cout << endl;
}int main()
{cin >> n >> m;for (int i = 0; i < m; i++){int x, y;cin >> x >> y;graph[x][y] = 1;}my_dfs();return 0;
}/*
input:
7 13
1 2
1 3
1 6
2 3
2 4
4 1
4 3
5 3
5 7
6 1
6 3
7 4
7 5output:
3 4 2 6 1 7 5
*/

广度优先遍历(BFS):

从图中某个节点出发,首先处理该节点指向邻居的所有边,然后将所有邻居放入一个调度器——队列(queue)中,接着处理该节点。下一个遍历的节点从当前被发现但未被处理的点中选出,即队列的首个节点,然后将其邻居节点依次放入队尾,处理该节点自身。重复以上过程,直到队列为空,所有节点均被处理完毕。

仍然以上面的图为例,输出BFS顺序遍历每个节点的值:

// BFS
#include <iostream>
#include <queue>
#define N 10000
using namespace std;int graph[N][N];
int color[N]; // 0 white, 1 grey, 2 black
int parent[N];
int dis[N];
int n, m;void bfs(int v)
{queue<int> que;color[v] = 1; // greydis[v] = 0; // 源点que.push(v);while(!que.empty()){int w = que.front();que.pop();for (int i = 1; i < n; i++){if (i != w && graph[w][i] == 1){if (color[i] == 0){color[i] = 1; //greyparent[i] = w;dis[i] = dis[w] + 1;que.push(i);}}}cout << w << " ";color[w] = 2; // black}
}void my_bfs()
{for (int i = 1; i <= n; i++){color[i] = 0;parent[i] = 0;dis[i] = 0;}for (int i = 1; i <= n; i++){if (color[i] == 0)bfs(i);}cout << endl;
}int main()
{cin >> n >> m;for (int i = 0; i < m; i++){int x, y;cin >> x >> y;graph[x][y] = 1;}my_bfs();return 0;
}/*
input:
7 13
1 2
1 3
1 6
2 3
2 4
4 1
4 3
5 3
5 7
6 1
6 3
7 4
7 5
output:
1 2 3 6 4 5 7
*/

网络中的最大流:

题目描述:

给定n个点,m条有向边,给定每条边的容量,求从点s到点t的最大流

输入:

第一行四个整数n,m,s,t。
接下来的m行,每行三个整数u,v,c,表示u到v,流量为c的一条边,

输出:

输出点s到点t的最大流。

样例输入 :

7 14 1 7
1 2 5
1 3 6
1 4 5
2 3 2
2 5 3
3 2 2
3 4 3
3 5 3
3 6 7
4 6 5
5 6 1
6 5 1
5 7 8
6 7 7

样例输出 :

14

提示:

1<=n<=100,1<=m<=5000,0<=c<=2147483647

#include <iostream>
#include <cstring>
using namespace std;const int N = 10001, E = 200001;int n, m, s, t;
long long ans = 0;
long long cnt = 1, first[N], nxt[E], to[E], val[E];inline void addE(int u, int v, long long w)
{to[++cnt] = v;val[cnt] = w;nxt[cnt] = first[u];first[u] = cnt;
}int dep[N], q[N], l, r;bool bfs()
{ memset(dep, 0, (n + 1) * sizeof(int));q[l = r = 1] = s;dep[s] = 1;while (l <= r) {int u = q[l++];for (int p = first[u]; p; p = nxt[p]) {int v = to[p];if (val[p] and !dep[v]) { dep[v] = dep[u] + 1;q[++r] = v;}}}return dep[t];
}long long dfs(int u, long long in)
{if (u == t)return in;long long out = 0;for (int p = first[u]; p and in; p = nxt[p]){int v = to[p];if (val[p] and dep[v] == dep[u] + 1) {long long res = dfs(v, min(val[p], in));val[p] -= res;val[p ^ 1] += res;in -= res;out += res;}}if (out == 0)dep[u] = 0;return out;
}int main()
{cin >> n >> m >> s >> t;for (int i = 1; i <= m; i++) {int u, v;  long long w;cin >> u >> v >> w;addE(u, v, w);addE(v, u, 0);}while (bfs())ans += dfs(s, 1e18);cout << ans << endl;return 0;
}
/**************************************************************Problem: 1006User: 201830210Language: C++Result: 正确Time:56 msMemory:0 kb
****************************************************************/

二分图中的最大匹配问题:

题目描述:

给定一个二分图,其左部点的个数为n,右部点的个数为m,边数为e,求其最大匹配的边数。

左部点从1至n编号,右部点从1至m编号。

输入:

输入的第一行是三个整数,分别代表n,m,e。

接下来输入e行,每行两个整数u,v,表示存在一条连接左部点u和右部点v的边。

输出:

输出一个整数,代表二分图最大匹配的边数。

样例输入:

4 2 7
3 1
1 2
3 2
1 1
4 2
4 1
1 1

样例输出:

2

提示:

1<= n,m <=100

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;int n,m;
int cnt=2;
int alist[6000001];
struct data
{int v;int next;int value;
}edge[6000001];void add(int u,int v,int value)
{edge[cnt].v=v;edge[cnt].value=value;edge[cnt].next=alist[u];alist[u]=cnt++;return ;
}
int h[1000001];
int q[1000001];bool bfs()
{int x,next;memset(h,-1,sizeof(h));int head=0,tail=1;q[head]=1;h[1]=0;while(head<tail){x=q[head++];next=alist[x];while(next){int v=edge[next].v;int value=edge[next].value;if(value&&h[v]<0){q[tail++]=v;h[v]=h[x]+1;}next=edge[next].next;}}if(h[n]==-1) return false;return true;
}int ans;
int dfs(int x,int y)
{if(x==n) return y;int next=alist[x];int w,used=0;while(next){int v=edge[next].v;int value=edge[next].value;if(value&&h[v]==h[x]+1){w=y-used;w=dfs(v,min(w,value));edge[next].value-=w;edge[next^1].value+=w;used+=w;if(used==y) return y;}next=edge[next].next;}if(!used) h[x]=-1;return used;
}
void dinic()
{while(bfs()) ans+=dfs(1,0x7fffffff);
}
int n1,m1,e1;
int main()
{scanf("%d%d%d",&n1,&m1,&e1);n=n1+m1+2;for(int i=1;i<=n1;i++){add(1,i+1,1);add(i+1,1,1);}for(int i=1;i<=e1;i++){int u,v;scanf("%d%d",&u,&v);if(u<=n1&&v<=m1)add(u+1,v+n1+1,1),add(v+n1+1,u+1,1);}for(int i=1;i<=m1;i++){add(i+n1+1,n,1);add(n,i+n1+1,1);}dinic();printf("%d",ans);return 0;
}
/**************************************************************Problem: 1005User: 201830210Language: C++Result: 正确Time:9 msMemory:0 kb
****************************************************************/

【算法】图论学习笔记与代码实现相关推荐

  1. 计算机视觉算法——Transformer学习笔记

    算机视觉算法--Transformer学习笔记 计算机视觉算法--Transformer学习笔记 1. Vision Transformer 1.1 网络结构 1.2 关键知识点 1.2.1 Self ...

  2. 聚类算法评价指标学习笔记

    聚类算法评价指标学习笔记 本文列举常用聚类性能度量指标,并列出相应代码与参考资料 聚类性能度量大致分两类,一类将聚类结果与某个"参考模型"(reference model)进行比较 ...

  3. 数据结构与算法-链表学习笔记

    数据结构与算法-链表学习笔记 链表的概念 链表是有序的列表. 链表是以节点的方式来存储,是链式存储,它在内存中并不是一定是连续的. 每个节点包含 data 域:存储数据, next 域:指向下一个节点 ...

  4. 算法训练营学习笔记1

    算法训练营学习笔记 贪心算法 心算法总是做出当前最好的选择,期望通过局部最优选择得到全局最优的解决方案.从问题的初始解开始,一步歩地做出当前最好的选择,逐步逼近问题的目标,尽可能得到最优解: 贪心本质 ...

  5. (实验38)单片机,STM32F4学习笔记,代码讲解【SD卡实验】【正点原子】【原创】

    文章目录 其它文章链接,独家吐血整理 实验现象 主程序 SD卡驱动程序 代码讲解 其它文章链接,独家吐血整理 (实验3)单片机,STM32F4学习笔记,代码讲解[按键输入实验][正点原子][原创] ( ...

  6. (实验39)单片机,STM32F4学习笔记,代码讲解【FATFS实验】【正点原子】【原创】

    文章目录 其它文章链接,独家吐血整理 实验现象 主程序 FATFS初始化程序 代码讲解 其它文章链接,独家吐血整理 (实验3)单片机,STM32F4学习笔记,代码讲解[按键输入实验][正点原子][原创 ...

  7. (实验55)单片机,STM32F4学习笔记,代码讲解【网络通信实验】【正点原子】【原创】

    文章目录 其它文章链接,独家吐血整理 实验现象 主程序 LWIP初始化程序 代码讲解 其它文章链接,独家吐血整理 (实验3)单片机,STM32F4学习笔记,代码讲解[按键输入实验][正点原子][原创] ...

  8. (实验37)单片机,STM32F4学习笔记,代码讲解【内存管理实验】【正点原子】【原创】

    文章目录 其它文章链接,独家吐血整理 实验现象 主程序 内存池初始化程序 代码讲解 其它文章链接,独家吐血整理 (实验3)单片机,STM32F4学习笔记,代码讲解[按键输入实验][正点原子][原创] ...

  9. [学习笔记]《代码整洁之道》(八)

    [学习笔记] <代码整洁之道>- 第9章 单元测试 TDD 三定律 谁都知道TDD要求我们在编写生产代码之前先编写单元测试. 定律一:在编写不能通过的测试单元前,不可以编写生产代码. 定律 ...

最新文章

  1. 回顾2017,展望2018
  2. Dropbox用户数增速恢复:突破5亿 9个月增加1亿
  3. 提高Web性能的前端优化技巧总结
  4. HDU - 4686 Arc of Dream(矩阵快速幂,水题)
  5. 解惑小微企业信息化系统上云的顾虑
  6. iOS开发Swift篇—(三)字符串和数据类型
  7. python随机生成k个不重复的随机数_使用Python生成不重复的随机值
  8. 谈Flash中的鼠标响应
  9. TreeList(一)
  10. python 加减法 负数_python解决两位数加减法快速出题问题
  11. 微信公众平台开发 整合百度云开放平台与微信开放平台
  12. Whois 查询违法?
  13. CTF题库实验吧 py的交易
  14. css版权备案等居于页面底部与超出不换行可滑动
  15. 二维码墓碑:可手机“扫”墓祭祖
  16. 萌娃第一台电动车哪吒魔小童正式交付
  17. steam游戏存档迁移
  18. Scons入门指南 使用教程 笔记
  19. Hashcat 使用教程
  20. 计算机图形基础学答案,计算机图形学基础答案全.pdf

热门文章

  1. Bean标签基本配置
  2. ClassLoader简介
  3. MapReduce-Reduce端join操作-步骤分析
  4. Ant Design入门之布局
  5. 字典-字典的统计、合并、清空操作
  6. c#如何使用反射去创建一个委托_【自学C#】|| 笔记 37 创建线程
  7. linux终端安装playonlinux,Ubuntu怎么安装PlayOnLinux
  8. 在 Java 中,为什么需要创建内部类对象之前需要先创建外部类对象
  9. 210106阶段三 文件I/O
  10. 一次性掌握JDK、JRE、JVM的概念以及三者之间的关系【2021整理】