zoukankan      html  css  js  c++  java
  • 图算法

    #include<iostream>
    using namespace std;
    //贪心法求单源最短路径
    template<class Type>

    void Dijkstra(int n,int v,Type dist[],int prev[],Type **c)
    {
    bool s[maxint];
    for(int i=1;i<=n;i++) //以V为出发点,初始化dist[i],s[i]和prev[i]的值
    {

    dist[i]=c[v][i];
    s[i]=false;
    if(dist[i]==maxint)
    prev[i]=0;
    else prev[i]=v;
    }
    dist[v]=0;s[v]=true;
    for(int i=1;i<n;i++) //共有n个点
    {

    int temp=maxint;
    int u=v;
    for(int j=1;j<=n;j++) //寻找到达所有路径点的最少值,这个是贪心算法的体现,选取最少值进行下一次的寻找
    if((!s[j])&&(dist[j]<temp)

    {
    u=j;temp=dist[j];
    }
    s[u]=true; //再以它为出发点
    for(int j=1;j<=n;j++)

    if((!s[j])&&(c[u][j]<maxint))
    {
    Type newdist=dist[u]+c[u][j];
    if(newdist<dist[j]) //更新其它所有的值
    {

    dist[j]=newdist;
    prev[j]=u;
    }
    }
    }
    }

    //Prim算法解决最少生成树
    template<class Type>

    void Prim(int n,Type **c)
    {
    Type lowcost[maxint]; //存储到各点的最短距离
    int closest[maxint]; //存储在S中的邻接顶点
    bool s[maxint];

    s[1]=true;
    for(int i=2;i<=n;i++) //初始化,以1为出发点
    {

    lowcost[i]=c[1][i];
    closet[i]=1;
    s[i]=false;
    }
    for(int i=1;i<n;i++) //共有n个顶点
    {

    Type min=inf;
    int j=1;
    for(int k=2;k<=n;k++) //全局比较,找出最少的lowcost,然后设为closet[j];
    if((lowcost[k]<min)&&(!s[k]))

    {
    min=lowcost[k];j=k;
    }
    cout<<j<<''<<closet[j]<<endl;
    s[j]=true; //作为下一个出发点
    for(int k=2;k<=n;k++)

    if((c[j][k]<lowcost[k])&&(!s[k])) //更新它于未访问集合的最短距离
    {

    lowcost[k]=c[j][k];
    closet[k]=j;
    }
    }
    }

    //Kruskal算法构建最少生成树
    template<class Type>

    class EdgeNode
    {
    friend ostream &operator<<(ostream&,EdgeNode<Type>);
    friend bool Kruskal(int ,int,EdgeNode<Type>*,EdgeNode<Type>*);
    friend void main(void);
    public:
    operator Type() const
    {
    return weight;
    }
    private:
    Type weight;
    int u,v;
    };

    template<class Type>
    bool Kruskal(int n,int e,EdgeNode<Type> E[],EdgeNode<Type> t[])
    {
    MinHeap<EdgeNode<Type>> H(1); //最少堆实现边的排序
    H.Initialize(E,e,e);

    UnionFind U(n); //用抽象数据类型并查集UnionFind
    int k=0;

    while(e&&k<n-1)
    {
    EdgeNode<int> x;
    H.DeleteMin(x);
    e--;
    int a=U.Find(x.u); //返回U中包含顶点u的连通分支的名字
    int b=U.Find(x.v);

    if(a!=b)
    {
    t[k++]=x;
    U.Union(a,b); //将U中两个连通分支a和b连接起来
    }

    }
    H.Deactivate();
    return (k==n-1);
    }

    //优先队列式分支界限法解决单源最短路径问题
    template<class Type>

    class Graph
    {
    friend void main(void);
    public:
    void ShortestPaths(int);
    private:
    int n, //图G的顶点数
    *prev; //前驱顶点数组
    Type **c, //图G的邻接矩阵
    *dist; //最短距离数组
    };


    template<class Type>
    class MinHeapNode
    {
    friend Graph<Type>;
    public:
    operator int() const
    {
    return length;
    }
    private:
    int i; //顶点编号
    Type length; //当前路长
    };


    //最少堆表示活结点的优先队列
    template<class Type>

    void Graph<Type>::ShortestPaths(int v)
    {
    //定义最少堆的容量为1000
    MinHeap<MinHeapNode<Type>> H(1000);

    //定义初始的扩展点
    MinHeapNode<Type> E;

    E.i=v;
    E.length=0;
    dist[v]=0;
    //搜索问题的解空间
    while(true)

    {
    for(int j=1;j<=n;j++)
    if((c[E.i][j]<inf)&&(E.length+c[E.i][j]<dist[j]))
    {//顶点i到顶点j可达,且满足控制约束
    dist[j]=E.length+c[E.i][j];

    prev[j]=E.i;
    //加入活结点优先队列
    MinHeapNode<Type> N;

    N.i =j;
    N.length=dist[j];
    H.Insert(N);
    }
    try
    {
    H.DeleteMin(E); //取下一个扩展点,相当于贪心法,选取最短距离作为出发点
    }

    catch(OutOfBounds) //优先队列空
    {

    break;
    }
    }
    }

    //分支界限算法与宽度优先搜索不同的是,优先队列活结点是最小堆,而宽度优先是队列(FIFO),没有优化。
    //回溯法与深度优先不同的是,回溯法拥有约束和剪枝函数,使解空间有可能缩小。



    Live together,or Die alone!
  • 相关阅读:
    Elasticsearch 索引文档如何使用自动生成 Id?
    Spring Boot 缓存 知识点
    table的各种用法
    Spring Boot 整合 Elasticsearch
    Spring Boot 集成 Kafka
    Spring Boot 2实现分布式锁——这才是实现分布式锁的正确姿势!
    Spring Cloud 与 Spring Boot 版本兼容关系
    Spring Boot 之:Spring Boot Admin
    JVM 性能调优工具
    Spring Boot 之:Actuator 监控
  • 原文地址:https://www.cnblogs.com/hzhida/p/2354716.html
Copyright © 2011-2022 走看看