zoukankan      html  css  js  c++  java
  • 图论三月小结

    三月算法学习总结

    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;
    }  

     

    想的太多,做的太少;
  • 相关阅读:
    李宏毅back propagation(lecturte7 )课堂笔记
    李宏毅deep learning(lecturte6)课堂笔记
    李宏毅classification+Logistic Regression(lecturte4+5)课堂笔记
    李宏毅Gradient Descent(lecturte3)课堂笔记
    02.get-post.php
    02.get-post
    01.php基础语法和JS区别.php
    11.子访问父
    10.父访问子--(children+refs)
    9.组件通讯(子传父)自定义事件
  • 原文地址:https://www.cnblogs.com/littlerita/p/12576610.html
Copyright © 2011-2022 走看看