zoukankan      html  css  js  c++  java
  • 清北学堂—2020.1提高储备营—Day 3(图论初步(二))

    qbxt Day 3

    ——2020.1.19 济南 主讲:李奥

    目录一览

    1.图论(kruskal算法,最短路径算法,拓扑排序)

    总知识点:图论

    一、kruskal算法
    1.目的:求图的最小生成树
    2.算法描述:
    先将所有的边按照权值从小到大排序,相同权值的边顺序随意。
    然后按顺序依次考虑将这些边加入最小生成树中:
    若加入这条边后,当前已加入的边出现环,则不加入这条边。
    若加入这条边后,当前已加入的边不出现环,则加入这条边。
    3.代码实现:

    qsort(a+1,m,sizeof(edge),cmp); //对边进行排序
    for(i=1;i<=n;i++) belong[i]=i;
    for(i=1;i<=m;i++){
    	if(belong[a[i].x]!=belong[a[i].y]){
    		ans+=a[i].k;
    		for(j=1;j<=n;j++){
    			if(belong[j]==belong[a[i].x])
                                belong[j]=belong[a[i].y];
        		}
        	}
    }
    

    二、最短路径
    1.最短路径指所经过的边的权值最小的路径。(以下讨论主要针对有向图。)
    2.算法:
    (1)SPFA算法
    解决问题:单元最短路

    注:边权可以为负但不能有负环

    最短路径的前缀也一定是最短路径

    SPFA算法需要借助队列,一般使用STL中的队列。
    注:STL的queue使用方法:
    z.push() 在队列尾加入一个元素

    z.pop() 弹出队列的队头

    z.front() 取队头

    z.empty() 判断队列非空
    算法时间复杂度上限:O(N^N)(上限是相当慢的)
    算法结构:
    先固定一个起始节点s(d[i]表示起始节点s节点到节点i的目前已知的最短距离)。
    最开始所有d[i]为inf,d[s]=0;(即什么都不知道)
    有一个等待更新别人的d值的队列z
    最开始只有s有资格更新别人,所以z.push(z)
    每次取出队列里的第一个节点,用他的d值更新与他相邻的节点的d值,被更新的节点又有资格更新别人,因此也加入队列。

    代码实现:

    z.push(s);
    v[s]=1;
    while(!z.empty()){
         x=z.front();
         z.pop();
         v[x]=0;
         for(k=first[x];k;k=a[k].next){
             y=a[k].y;
             if(d[x]+a[k].k<d[y]){
                 d[y]=d[x]+a[k].k;
                 if(!v[y]){
    		z.push(y);
    		v[y]=1;
    	     }
             }     
         }
    }
    
    

    (2)Floyd算法
    解决问题:所有节点之间的最短路

    时间复杂度:O(n^3)

    思想:
    Dp :f[k][i][j]表示从i到达j,中途经过的节点的编号必须小于等于k的情况的最短路。

    初始化f[0][i][j]即为邻接矩阵。

    代码:

    for(k=1;k<=n;k++)
      for(i=1;i<=n;i++)
         for(j=1;j<=n;j++)
             f[k][i][j]=min(f[k-1][i][j],f[k-1][i][k]+f[k-1][k][j]);
    //采用滚动数组: 
    for(k=1;k<=n;k++)
      for(i=1;i<=n;i++)
         for(j=1;j<=n;j++)
             f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
    

    三、拓扑排序:
    拓扑图:有向无环图

    拓扑排序:
    对于拓扑图的点进行排序,使得若有一条边x->y,则x一定排在y前面。
    找到第一个节点之后,将这个节点从图中删除,重复直到原图的点全部被删除。
    代码实现:

    for(i=1;i<=n;i++){
        if(d[i]==0)z.push(i);
    }
    while(!z.empty()){ 
        x=z.front();
        z.pop();
        A[++len]=x;
        for(k=first[x];k;k=a[k].next){
            y=a[k].y;
            d[y]--;
            if(d[y]==0) z.push(y);
        }
    }
    

    -------------------------------------------------------THE END------------------------------------------------

    本文欢迎转载,转载时请注明本文链接
  • 相关阅读:
    假期每日小结_2.2
    假期每日小结_2.1
    《新浪微博用户兴趣建模系统架构》阅读笔记
    《微博深度学习平台架构和实践》阅读笔记
    《亿级用户下的新浪微博平台架构》阅读笔记
    JavaScript中JSON的序列化和解析
    Servlet中@WebServlet("XXXX")注解无效,访问servlet报404错误
    数据卷(Data Volumes)
    Docker安装及基本命令
    springcloud服务配置中心
  • 原文地址:https://www.cnblogs.com/-pwl/p/12302175.html
Copyright © 2011-2022 走看看