拓扑排序学习

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

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

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

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

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



深度优先搜索拓扑排序 算法思想:用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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值