拓扑排序

拓扑排序

拓扑排序 百度百科:对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边<u,v>∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。

拓扑排序的操作:

  1. 找到图中入度为0的一个点。
  2. 删除该点和该点连接的边。
  3. 循环一二步骤,直到图中没有点或者不存在入度为0的点,需要注意的是,第二中情况表明图中存在环。

因此,拓扑排序(Topological sort)的前提是图为有向无环图(Dericted acyclic graph)。

例题HDU 1285

操作很简单,找点、删边即可,上题中存图用邻接矩阵、邻接表、链式前向星都可,我用的是链式前向星。

AC代码:

ll degree[510];
ll head[510];
ll ct = 1;

struct node
{
    ll v, next;
} edge[250010];
void add(ll u, ll v)
{
    edge[ct].v = v;
    edge[ct].next = head[u];
    head[u] = ct++;
}
ll n, m;
ll ans[510], cot = 1;
void tuopu()
{
    while (1)
    {
        ll now;
        for (int i = 1; i <= n; i++)
        {
            if (!degree[i])
            {
                now = i;
                degree[i] = 1;
                break;
            }
        }
        ans[cot++] = now;
        now = head[now];
        for (int i = now; i; i = edge[i].next)
            degree[edge[i].v]--;
        if (cot > n)
            break;
    }
}
int main()
{
    while (cin >> n >> m)
    {
        cot = ct = 1;
        fill(head, head + 501, 0);
        fill(degree, degree + 501, 0);
        for (int i = 1; i <= m; i++)
        {
            ll a, b;
            cin >> a >> b;
            degree[b]++;
            add(a, b);
        }
        tuopu();
        cout << ans[1];
        for (int i = 2; i < cot; i++)
            cout << ' ' << ans[i];
        cout << endl;
    }
    return 0;
}

上面的写法时间复杂度最坏 O ( n 2 ) O(n^2) O(n2),可以用队列维护入度为0的结点信息,时间复杂度降至 O ( n ) O(n) O(n)

传送门

核心代码:

int rk[100010], cnt = 0;
void topological()
{
    int id = 1;
    for (int i = 1; i <= n; i++)
        if (!degree[i])
            rk[++cnt] = i, vis[i] = 1;
    while (id <= n)
    {
        int pos = rk[id++];
        for (int i = head[pos]; i; i = edge[i].next)
        {
            int v = edge[i].v;
            degree[v]--;
            if (degree[v] == 0)
                rk[++cnt] = v, vis[v] = 1;
            dp[v] = max(dp[v], dp[pos] + 1);
        }
    }
}
参考资料
  1. 拓扑排序讲解
  2. 拓扑排序(Topological Sorting)
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hesorchen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值