深度优先DFS和广度优先BFS,破圈法,拓扑序列,prim,克鲁斯卡尔等生成算法(需要用到并查集)迪杰斯特拉算法和弗洛伊德的总结

1.有向图:比较好
2.无向图是变态的有向图,需要注意度和节点之类的比如MST,最小生成树利用破圈法生成,关联的度为1的无向图节点肯定不是回路(不知道对不。。),1.找到图中的一个圈。2.删除其中的权最大的边。3.重复上述操作,直到图中已无圈。
针对无向图,可以这样做:
1.用拓扑分类算法,找到图中的圈。具体就是依次找到图中度为1的顶点(可以保存在队列里),删除之(这里的删除是暂时的,下次遍历还要还原这些点),然后与其邻接的顶点的入度-1,这样往复操作,直到图中已不存在入度为1的顶点,即所有的顶点的度都》=2,那么剩下的边就都在环里了。当然,如果没剩下边,说明没有环,算法结束。
2.剩下的边就都是环中的边了,找一个权最大的删去即可。

3.再进行1操作,直到图中无圈,即所有的圈都已破掉,剩下的就是最小生成树了。

还有DFS和BFS:
深度优先DFS和广度优先BFS的区分并不是看遍历结果

而是策略上的区分
简单说,深度优先 就是从某个点出发,依次递归深度优先遍历其每个未被访问的邻接点
广度优先,是从某个点出发,依次遍历其每个未被访问的邻接点(并做记录),再对之前一步记录的每个邻接点,重复上述过程
节点可变
3.还有prim,克鲁斯卡尔等生成算法(需要用到并查集)
4.迪杰斯特拉算法和弗洛伊德注重过程,怎么一步步来的,挺重要的
5.还有关键路径
关键路径分析

如图,每个节点表示一个必须执行的动作以及完成动作所花费的时间。该图叫做动作节点图。图中的边代表优先关系,一条边(v,w)意味着动作v必须在动作w开始前完成。(这意味着这个图必然是无圈的)。
这个图可以模拟两类问题:
1. 整个方案最早什么时间完成?
2. 确定哪些动作时可以延迟的,延迟多长,而不致影响最少完成时间?
我们把动作节点图转化为事件节点图
1. 每个事件对应一个动作和所有相关的动作的完成;
2. 从事件节点图中的节点v可达到的事件可以在事件v完成后开始;
3. 在一个动作依赖于几个其他动作的情况下,可能需要插入哑边和哑节点(保证每个真实点只有一条入边)。

为了找出方案的最早完成时间,我们只要找出从第一个事件到最后一个事件的最长路径长度。
由于这是个无圈图,可以采纳最短路径算法计算图中所有节点的最早完成时间。
如果ECi是节点i的最早完成时间,则有
1. EC1 = 0;
2. ECw = max(ECv + c(v,w))

用以下法则计算每个节点最晚完成时间
1. LCn = ECn;//最后一个点的最晚完成时间和最早完成时间相同
2.LCv = min(LCw - c(v,w))

对于每个顶点,通过保存一个所有邻接且在先的顶点的表,这些值就可以以线性时间算出。借助顶点的拓扑顺序计算它们的最早完成时间,而最晚完成时间则通过倒转它们的拓扑顺序来计算。
拓扑排序-》有向图


#include <iostream>
#include<stack>
#include<queue>
#include "MinHeap.h"
#include "MaxHeap.h"
using namespace std;
class UFsets{
private:
    int n;
    int *root;
    int *next;
    int *length;
public:
    UFsets(int size)
    {
        n=size;
        root =new int[n];
        next =new int [n];
        length=new int [n];

        for(int i=0;i<n;i++)
        {
            root[i]=next[i]=i;
            length[i]=1;
        }

    }
    int Find(int v)
    {
        return root[v];

    }
    void Union(int v,int u)
    {
        if(root[v]==root[u])
            return;
        else if(length[root[v]]<length[root[u]])
        {

            int rt=root[v];
            length[root[u]]+=length[rt];
            root[rt]=root[u];
            for(int j=next[rt];j!=rt;j=next[j])
            {
                root[j]=root[u];

            }
            std::swap(next[rt],next[root[u]]);
        }
        else
        {
            int rt=root[u];
            length[root[v]]+=length[rt];
            root[rt]=root[v];
            for(int j=next[rt];j!=rt;j=next[j])
            {
                root[j]=root[v];

            }
            std::swap(next[rt],next[root[u]]);
        }

    }
};
template<class T>

class Edge
{
  public:
      int start,end;
      T weight;
      Edge(int st,int ed,int w){start=st;end=ed;weight=w;};
      Edge(){weight=0;end=-1;};
      bool operator >(Edge one)
      {

            return weight>one.weight;
      };
      bool operator <(Edge one)
      {
          return weight<one.weight;
      };
};
template<class T>
class AdjGraph
{
public:
    int vertexNum;
    int edgeNum;
    int *Mark;
    int **marix;

    int getVertexNum(){return vertexNum;};
    int getEdgesNum(){return edgeNum;};
    bool IsEdge(Edge<T> one)
    {
        if(one.weight>0&&one.end>=0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    int startVertex(Edge<T>one)
    {
        return one.start;
    }
    int endVertex(Edge<T>one)
    {
        return one.end;
    }
    T Weight(Edge<T> one)
    {
        return one.weight;
    }

    AdjGraph(int verticeNum)
    {
          vertexNum=verticeNum;
        edgeNum=0;

        vertexNum=verticeNum;
        Mark= new int[vertexNum];
        for(int i=0;i<vertexNum;i++)
        {
            Mark[i]=0;
        }
        int i,j;
        marix=new int*[vertexNum];
        for(i=0;i<vertexNum;i++)
            marix[i]=new int[vertexNum];
        for(i=0;i<vertexNum;i++)
            for(j=0;j<vertexNum;j++)
                marix[i][j]=9999;

    }
    ~AdjGraph()
    {

        for(int i=0;i<vertexNum;i++)
            delete []marix[i];
        delete []marix;
    }
    Edge<T> FirstEdge(int one)
    {
        Edge<T> tempEdge;
        tempEdge.start=one;
        for(int i=0;i<vertexNum;i++)
        {
            if(marix[one][i]!=0)
            {
                tempEdge.end=i;

                tempEdge.weight=marix[one][i];
                break;
            }
        }

        return tempEdge;
    }
    Edge<T> NextEdge(Edge<T> one)
    {
         Edge<T> tempEdge;
         tempEdge.end=-1;
        tempEdge.start=one.start;
        for(int i=one.end+1;i<vertexNum;i++)
        {
            if(marix[one.start][i]!=0)
            {
                tempEdge.end=i;
                tempEdge.weight=marix[one.start][i];
                break;
            }
        }
        return tempEdge;
    }
    void setEdge(int start,int end,T weight)
    {
        if(marix[start][end]==9999)
        {
            edgeNum++;
        }
        marix[start][end]=weight;

    }
    void delEdge(int start,int end)
    {
        if(marix[start][end]!=0)
        {
            edgeNum--;
        }
        marix[start][end]=0;
    }
    void visit(int v)
    {
         cout<<v+1<<endl;
    }
    void DFS(int i)
    {
        Mark[i]=1;
        visit(i);

        for(int j=0;j<vertexNum;j++)
        {
            if(marix[i][j]!=9999&&(Mark[j]==0))
            {
                DFS(j);
            }
        }
    }

   void  DFSTraverse()
    {
        for(int i=0;i<vertexNum;i++)
        {
            Mark[i]=0;
        }
        for(int i=0;i<vertexNum;i++)
        {
            if(Mark[i]==0)
            DFS(i);
        }
    }
    void DFSNoReverse()
    {
        int i;
        using std::stack;
        stack<int >s;
        for(i=0;i<vertexNum;i++)
        {
            Mark[i]=0;
        }
        cout<<1<<endl;
    for(int i = 0; i <vertexNum; i++)
    {
        if(marix[i][0]!=9999&& !Mark[i] )/*先存储到栈不访问*/
        {
            Mark[i] =  1;
            s.push(i);
        }
    }
      while(!s.empty())
       {
        int s_top =  s.top();
        Mark[s_top] = 1;
        visit(s_top);
        s.pop();
        for(int i = 1; i <= vertexNum-1; i++)
        {
            if(marix[i][s_top]!=9999 && !Mark[i] )/*先存储到栈不访问*/
            {
                Mark[i] = 1;
                s.push(i);
            }
        }
    }
        }
void Dijkstra(T mar[6][6],int n,int v,int flag[],int path[])
{
    int *dist=new int[n];


    for(int i=0;i<n;i++)
    {
        dist[i]=mar[v][i];
        path[i]=v;
        flag[i]=0;
    }
    flag[v]=1;

    for(int i=0;i<n-1;i++)
    {    int min=9999;
         int k=0;
        for(int i=0;i<n;i++)
        {
            if(!flag[i])
            {
                if(dist[i]<min)
                {
                    min=dist[i];
                    k=i;

                }
            }
        }
        cout<<k<<" "<<endl;
        flag[k]=1;/*添加到集合*/
         for(int j=0;j<n;j++)
        {
        if(!flag[j])
            {
            if(dist[j]>(dist[k]+mar[k][j]))
                {
                    path[j]=k;
                    dist[j]=dist[k]+mar[k][j];
                }
            }
        }
    }
    cout<<"Path---";
    for(int i=0;i<n;i++)
    {
        cout<<path[i]<<" ";
    }
   cout<<endl;

}
void BFSTraverse()
    {
        int v;
        for(v=0;v<vertexNum;v++)
            Mark[v]=0;
        int start=0;
        visit(start);
        Mark[start]=1;
        using std::queue;
        queue<T >q;
        q.push(start);
        while(!q.empty())
        {
            T temp=q.front();
            q.pop();
            if(!Mark[temp])
            {
                visit(temp);
                Mark[temp]=1;
            }
            for(int i=0;i<vertexNum;i++)
            {
                if(marix[temp][i]!=9999&&(!Mark[i]))
                    q.push(i);
            }
        }
    }
 AdjGraph Prim()
 {
    int lowcost[vertexNum],vset[vertexNum],v,lowcostr[vertexNum];
    int i,j,k,min,r;
    int sum=0;
    AdjGraph a(vertexNum);

    for(i=0;i<vertexNum;i++)
    {
        lowcost[i]=marix[0][i];/*lowcost[] represents the minimal weight (Tree->node minweight)*/
        vset[i]=0;/*wheater exist in the tree*/
        lowcostr[i]=0;
    }
    vset[0]=1;/*insert to the tree*/

    for(i=0;i<vertexNum-1;i++)/*insert n-1 times*/
    {
        min=99999;
        for(j=0;j<vertexNum;j++)//寻找未访问的最小边的节点
        {
            if(vset[j]==0&&lowcost[j]<min)
            {
                r=lowcostr[j];
                min=lowcost[j];
                k=j;
            }

        }
        vset[k]=1;
        a.setEdge(r,k,min);
        a.setEdge(k,r,min);
        sum+=min;
        v=k;
        for(j=0;j<vertexNum;j++)//更新最小边
        {
            if(vset[j]==0&&marix[v][j]<lowcost[j])
            {

                lowcostr[j]=v;
                lowcost[j]=marix[v][j];
            }
        }

    }
    cout<<"the sum of weight is "<<sum<<endl;
    return a;
 }
 AdjGraph Kruskal()
 {
     int n=vertexNum;
     UFsets set(n);
     AdjGraph<T> b(n);
     int sum=0;
     MinHeap<Edge<T> > h(edgeNum/2);
     Edge<T> edge;
     for(int i=0;i<vertexNum;i++)
     {
         for(int j=0;j<vertexNum;j++)
         {
             if((j>i)&&(marix[i][j]!=9999))
             {  Edge<T>a(i,j,marix[i][j]);
                 h.insert(a);

             }
         }
     }
     int edgenums=0;

     while(edgenums<n-1)
     {
         if(!h.empty())
         {
             h.deleteTop(edge);//找最小边
             int v=edge.start;
             int u=edge.end;
             if(set.Find(v)!=set.Find(u))//合并最小
             {
                 set.Union(v,u);//并查集
                 b.setEdge(edge.start,edge.end,edge.weight);
                 b.setEdge(edge.end,edge.start,edge.weight);
                 edgenums++;
             }
         }
     }

     return b;
 }
 void Floyd(int adj[3][3],int path[3][3])
 {
     int i,j,k,v;
     for(i=0;i<vertexNum;i++)
     {
         for(j=0;j<vertexNum;j++)
         {
             if(i==j)
             {
                 adj[i][j]=0;
                 path[i][j]=i+1;
             }
             else
             {
                 adj[i][j]=9999;
                 path[i][j]=-1;
             }


         }


     }
     for(v=0;v<vertexNum;v++)//初始化
     {
         for(j=0;j<vertexNum;j++)
         {   if(marix[v][j]!=9999)
             adj[v][j]=marix[v][j];
             else
                adj[v][j]=0;

             path[v][j]=v+1;
         }
     }
     for(v=0;v<vertexNum;v++)
        {for(i=0;i<vertexNum;i++)
          {

           for(j=0;j<vertexNum;j++)
            {if(adj[i][j]>(adj[i][v]+adj[v][j]))
                 {
                    adj[i][j]=adj[i][v]+adj[v][j];
                        path[i][j]=v+1;
                  }
            }
        }
        }

     for(int i=0;i<vertexNum;i++)
     {
         for(int j=0;j<vertexNum;j++)
            cout<<path[i][j]<<" ";
        cout<<endl;
     }


 }
 void FindcycleByTopogySort(int ** marix,int *SortArray)
 {
     int *indegree=new int[vertexNum];
     int v;
     for(v=0;v<vertexNum;v++)//init
     {
         indegree[v]=0;
         Mark[v]=0;
     }
     for(v=0;v<vertexNum;v++)//统计入度个数
     {
         for(int j=0;j<vertexNum;j++)
         {
             if(marix[v][j]==1)
             {
                 indegree[j]++;
             }
         }
     }
     for(int i=0;i<vertexNum;i++)
     {
         for(v=0;v<vertexNum;v++)
         {
             if(indegree[v]==0&&Mark[v]==0)
             {
                 break;
             }
         }
         if(v==vertexNum)
         {
             for(int i=0;i<vertexNum;i++)
             {
                 if(!Mark[i])
                 {    DFS(i);
                     break;
                 }
             }

         }
         else
         {
             Mark[v]=1;
             SortArray[i]=v;
             for(int j=0;j<vertexNum;j++)
             {
                 if(marix[v][j]==1)
                 {
                     indegree[j]--;
                 }
             }
         }
     }

 }

 void MSTByTopogySort()
 {
     AdjGraph<int> adj(vertexNum);
     int *indegree=new int[vertexNum];
     int v;
     int count=edgeNum/2;
     int flag=1;
     int flag2=1;
     while(count>vertexNum-1)
     {
         for(v=0;v<vertexNum;v++)//init
        {
            indegree[v]=0;
            Mark[v]=0;
         }
     for(v=0;v<vertexNum;v++)//统计入度个数
       {
            for(int j=0;j<vertexNum;j++)
           {
               adj.marix[v][j]==marix[v][j];
               if(marix[v][j]!=9999)
             {
                 indegree[j]++;
             }
         }
     }
for(int i=0;i<vertexNum;i++)
{
    cout<<indegree[i]<<endl;
}
        flag=1;
     for(int i=0;i<vertexNum&&flag;i++)
     {

         for(v=0;v<vertexNum;v++)
         {
             if(((indegree[v]==1))&&Mark[v]==0)
             {

                 break;
             }
         }
         if(v==vertexNum)
         {


             int flag1=1;

             for(int i=0;i<vertexNum;i++)
             {
                 if(!Mark[i])
                 {
                      Mark[i]=1;
                      int b=i;
                      MaxHeap<Edge<T> > e(edgeNum/2);
                   for(int a=i;a<vertexNum&&flag1;a++)
                   {

                     for(int j = i; j <vertexNum&&flag1; j++)
                    {
                           if(indegree[j]==1)
                           {
                               flag1=0;
                           }
                    }
                  }
                  if(flag1)
                {
                    for(int a=b;a<vertexNum&&flag1;a++)
                   {

                     for(int j = b; j <vertexNum&&flag1; j++)
                    {
                          Edge<T>ee(a,j,marix[a][j]);
                          if(j>a&&(marix[a][j]!=9999))
                          {
                              e.insert(ee);
                          }

                    }
                  }
                }
                  Edge<T>ee;
                  e.deleteTop(ee);
                  adj.marix[ee.start][ee.end]=9999;
                  adj.marix[ee.end][ee.start]=9999;
                  cout<<"bian"<<ee.start+1<<" "<<ee.end+1<<" "<<ee.weight<<endl;
                  marix[ee.start][ee.end]=9999;
                  marix[ee.end][ee.start]=9999;
                  indegree[ee.start]--;
                  indegree[ee.end]--;
                  count--;
                  flag=0;

                  break;
                }
             }



         }
         else
         {
             Mark[v]=1;

             for(int j=0;j<vertexNum;j++)
             {
                 if(marix[v][j]!=9999)
                 {
                     indegree[j]--;
                     indegree[v]--;
                 }
             }

         }

     }
 }
 DFSNoReverse();
 }
};


int main()
{
  /* AdjGraph<int >d(8);
    d.setEdge(0,1,1);
    d.setEdge(0,2,1);
    d.setEdge(1,3,1);
    d.setEdge(1,4,1);
    d.setEdge(3,7,1);
    d.setEdge(4,7,1);
    d.setEdge(2,5,1);
    d.setEdge(2,6,1);
    d.setEdge(5,6,1);
    d.setEdge(6,5,1);
    d.setEdge(6,2,1);
    d.setEdge(5,2,1);
    d.setEdge(7,4,1);
    d.setEdge(7,3,1);
    d.setEdge(4,1,1);
    d.setEdge(3,1,1);
    d.setEdge(2,0,1);
    d.setEdge(1,0,1);
   /* for(int i=0;i<a.getVertexNum();i++)
        {
            for(int j=0;j<a.getVertexNum();j++)
        cout<<a.marix[i][j];
        cout<<endl;
        }

   cout<<"DFS-"<<endl;
    d.DFSNoReverse();
    cout<<"BFS-"<<endl;
   d.BFSTraverse();
   cout<<"DFS-(digui)"<<endl;
   d.DFSTraverse();*/
  AdjGraph<int> a(6);
  a.setEdge(0,1,6);
  a.setEdge(0,3,5);
  a.setEdge(0,2,1);
  a.setEdge(1,2,5);
  a.setEdge(1,4,3);
  a.setEdge(2,4,6);
  a.setEdge(2,5,4);
  a.setEdge(2,3,5);
  a.setEdge(3,5,2);
  a.setEdge(4,5,6);
  a.setEdge(1,0,6);
  a.setEdge(3,0,5);
  a.setEdge(2,0,1);
  a.setEdge(2,1,5);
  a.setEdge(4,1,3);
  a.setEdge(4,2,6);
  a.setEdge(5,2,4);
  a.setEdge(3,2,5);
  a.setEdge(5,3,2);
  a.setEdge(5,4,6);
  AdjGraph<int> b(6);
b=a.Kruskal();
cout<<"------------------------------Kruskal--------------"<<endl;
  for(int i=0;i<b.getVertexNum();i++)
        { cout<<i+1<<" ";
            for(int j=0;j<b.getVertexNum();j++)
        cout<<b.marix[i][j]<<" ";
        cout<<endl;
        }
cout<<"------------------------------Prim--------------"<<endl;
      AdjGraph<int> c(6);
c=a.Prim();
  for(int i=0;i<c.getVertexNum();i++)
        { cout<<i+1<<" ";
            for(int j=0;j<c.getVertexNum();j++)
        cout<<c.marix[i][j]<<" ";
        cout<<endl;
        }
/*AdjGraph<int> c(6);
  c.setEdge(0,2,10);
  c.setEdge(1,2,5);
  c.setEdge(0,4,30);
  c.setEdge(0,5,100);
  c.setEdge(2,3,50);
  c.setEdge(3,5,10);
  c.setEdge(4,3,20);
  c.setEdge(4,5,60);
  int flag[6];
  int path[6];
  c.Dijkstra(c.marix,c.vertexNum,0,flag,path);
    return 0;*/
  /*  AdjGraph<int> e(3);
    e.setEdge(0,2,5);
    e.setEdge(2,0,2);
    e.setEdge(2,1,13);
    e.setEdge(1,2,6);
    e.setEdge(0,1,10);
    e.setEdge(1,0,9);
    int path[3][3];
    int adj[3][3];
    e.Floyd(adj,path);*/
AdjGraph<int> f(4);
    f.setEdge(0,1,1);
    f.setEdge(0,2,1);
    f.setEdge(2,1,1);
    f.setEdge(3,2,1);
    f.setEdge(1,3,1);
    int dd[5];
    f.FindcycleByTopogySort(f.marix,dd);
   /*AdjGraph<int> a(6);
  a.setEdge(0,1,6);
  a.setEdge(0,3,5);
  a.setEdge(0,2,1);
  a.setEdge(1,2,5);
  a.setEdge(1,4,3);
  a.setEdge(2,4,6);
  a.setEdge(2,5,4);
  a.setEdge(2,3,5);
  a.setEdge(3,5,2);
  a.setEdge(4,5,6);
  a.setEdge(1,0,6);
  a.setEdge(3,0,5);
  a.setEdge(2,0,1);
  a.setEdge(2,1,5);
  a.setEdge(4,1,3);
  a.setEdge(4,2,6);
  a.setEdge(5,2,4);
  a.setEdge(3,2,5);
  a.setEdge(5,3,2);
  a.setEdge(5,4,6);
  a.MSTByTopogySort();*/
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值