拓扑排序学习

来源:互联网 发布:网络信息安全注意事项 编辑:程序博客网 时间:2024/05/29 14:06

其实早就应该学习一下拓扑排序了,而且之前有几次也确实遇到了这类的问题,但是由于我的懒惰却一直没有真正的拿出时间去掌握它,或者看两眼没看懂也就算了。

之前也看过博客上的一些介绍,但是总感觉理论性太强,也太长了,没耐心看。其实真正学习图论的话这些基础的理论知识还是十分关键的。

学习图论的时候总是有这样的感觉,就是觉得虽然代码可能会写,但是没有系统的学习理论知识,所以做起题来总是不太可靠,稳定性不够。其实我也根本没怎么学过图论的东西,以后应该系统学习。

但是作为入门,所以先不要求自己具备多么系统的理论基础了,先把算法和代码实现理解了再说吧。

其实最后让我真正看明白的还是《算法竞赛入门经典》这本书。这本书上介绍的是深度搜索的拓扑排序。和算法导论上介绍的算法一样。



深度优先搜索拓扑排序 算法思想:用DFS遍历整个图,得出个节点的完成时间,然后按完成时间倒序排列就得到了图的拓扑排序序列

int G[30][30];int n,m;int c[30];int topo[30];int t;bool dfs(int u){    c[u]=-1;    for(int v=0; v<n; v++) if(G[u][v])        {            if(c[v]<0) return false;            else if(!c[v] && !dfs(v)) return false;        }    c[u]=1;    topo[--t]=u+1;    return true;}bool toposort(){    t=n;    memset(c,0,sizeof(c));    for(int u=n-1; u>=0; u--) if(!c[u])        {            if(!dfs(u)) return false;        }    return true;}


还有一种是广度优先搜索求拓扑排序的。

基本思想:(1)从有向图中选择一个没有前驱(即入度为0)的顶点并且输出它.(2)从网中删去该顶点,并且删去从该顶点发出的全部有向边.(3)重复上述两步,直到剩余的网中不再存在没有前趋的顶点为止.

int topo[1001];int G[1005][1005];int indegree[1005];int n,m;bool toposort()     /// G[0,n){    int cnt=0,i,j,k;    for(i=0;i<n;i++)       // 执行n次删点操作    {        for(j=0;j<n;j++)   // 循环找入度为0的点        {            if(indegree[j]==0)            {                indegree[j]--;    // 删除该点                topo[cnt++]=j+1;  // 记录拓扑序                for(k=0;k<n;k++)  //删除与该点相连的边                    if(G[j][k]) indegree[k]--;                break;            }            if(j==n-1)     //如果没找到入度为0的点,即成环            {                return false;            }        }    }    return true;}


0 0
原创粉丝点击