图论三月小结

三月算法学习总结

2020-3-23

一:图论基本算法:

 

小提纲:

几个概念:

度数:无向图中一个点连出去的边数

联通:两个点通过路径相连

拓扑图:没有环的图、

三无图:无向,无重边,无自环

割点:删除这个点之后图不连通

桥边: 删除这个边之后图不连通

强联通:有向图中,两个点可以互相到达

强联通分量( SCC):有向图中,分量中所有点可以互相到达

点双联通分量:没有割点;

边双联通分量:没有割边;

 

几个结论:

1.一个图里的树边必然是n-1

2.二分图里:

最小点覆盖最大匹配最大独立集总点数最小点覆盖

 

*1.1 最短路总结(较重要):**

 

其实bfs解决最短路是没问题的,感觉bfs启发了最短路算法。

算法数据规模复杂度数据结构边权用法
floyd 200 O(n^3) 邻接矩阵 有负 解决一些其他问题挺方便
spfa >=1e7 O(n*m) 邻接表,前向星 有负 随机数据线性时间,网格图可以拉满复杂度,可判负边,比较好写
dijkstra >=1e7 O(m*log(n)) 邻接表,前向星 无负 较快通用算法

floyd求传递闭包:

听着挺牛逼的概念,其实挺简单的东西,a和d没有直连边,但a通过b,c又可以走到d,所以a可以走到d。

 

 

例:zoj-4124;求闭包传递。

1.2 差分约束:

解决一系列线性规划问题:

 

把x1,x2,等等,看做最短路节点,

跑一遍spfa,对于每一条边起点u,终点v,都有:

 

那么在求解最短路的时候,实际上是得到一组最大解(因为 若干个 = 的成立)。

求解最长路,得到的是一组最小解。

 

板题:poj3159

跑一遍spfa,前向星+模拟队列,不然TLE

 

 

1.3 拓扑图

做法:

按顺序跑一遍,可以bfs,dfs,个人喜欢bfs。

做法:找出入度为0的点,开始广搜。

用法:

  1. 判断有没有环:拓扑时记录出队人数,小于n必有环。

  2. 当拓扑队列里人数超过2时,说明有排名并列。

例题:

T123571 Misaka Network

按拓扑序选择,

记得当时犯了一个逻辑错误:一个点不是控制点,就是如果有控制点连到它就行了。

但,一个点是控制点,不是说连到它的点不是控制点就行了,只要有一个连到它的控制点,那它就不是控制点。

 

1.4 欧拉路(一笔画)

做法:

无向图:

第一步:判断是否联通,并查集解决;

第二步:

所有点度数为偶数欧拉回路起点,终点度数为奇数,其余点度数为偶数欧拉路其他都不是
有向图:

第一步:判断是否联通,并查集解决;

第二步:记录出入度数

所有点入出欧拉回路起点出入,终点入出,其他点入出欧拉路其他都不是

例题:

B - Grid with Arrows

网格图欧拉路,开不了数组,蛋疼的动态过不了,哈希处理

 

1.5 无向图求割点及割边

tarjan算法:

 

 

一张图搞成一颗dfs树;

low数组表示可到达祖先,dep表示递归深度;

如果 low[v]>=num[u],说明是割点;

如果 low[v]>num[u] 说明是割边;

如果 num[v]<num[u]&&v!=fa,说明是回退边,

 

求构成边连通分量的最小边:

 

 

运用缩点技术:

在dfs的时候,low值相同的点必然在一个边双联通分量里,把每一个双连通分量压缩成为一个点求解。

 

image-20200323232533082

 

1.6 有向图求强联通分量

 

还是tarjan算法

有以下结论:

1.一个强联通分量的所有的可以互相访问,low值相同。

2.用栈保存节点(注意是边,而不是点),dfs撞到 low=dep的点 ,把栈里元素全抖出来,构成一个SCC。

 

1.7 最小生成树

贪心取边+并查集联通(较简单)复杂度(O(E log(E)+E))

 

1.8 二分图匹配(较重要)

如图:一个图分成了两个部分,这两个独立集内部都没有边,这就是一个二分图。

几个结论:

最小点覆盖最大匹配最大独立集总点数最小点覆盖

 

 

 

 

 

如何判断一个图可以搞成二分图?

采用染色法,每两个相邻的点必然不在一个独立集里,把他们染成不同的颜色。

二分图等价于没有奇环的图

如果有奇环,染色染出来必然矛盾。

 

二分图匹配(匈牙利算法)

较简单,

 

 

点u,v可以匹配,当且仅当 u,v都还未匹配,或者u已经匹配的点可以换人匹配,最终使得u,v匹配。

写法:

bool findpath(int u){
   for(int i=0;i<e[u].size();i++){
   int v=e[u][i];
   if(!vis[v]){
   vis[v]=1;
   if(!match[v]||findpath(match[v])){
  match[v]=u;
  return 1;
  }
  }
  }
   return 0;
}  

 

posted @ 2020-03-26 19:08  无声-黑白  阅读(165)  评论(0编辑  收藏  举报