• 【图论】Prufer序列


    凯莱定理:n个点的完全图的生成树有n^(n-2)个。

    长度为n-2,值域为[1,n]的Prufer序列和一个n个节点编号分别为[1,n]的无向连通图的生成树双射。

    无根树变Prufer:每次选择一个编号最小的叶子删除他,在序列中记录其父亲,直到剩下最后的两个点。(假如再做一步,则Prufer序列一定以n号点结尾,毫无意义)
    用个堆也可以,直接用一个指针也可以。

    下面把n-1位置也放上Prufer,为了统一处理。

                for(int i = 1; i <= n; ++i) {
                    deg[i] = G[i].size();
                    vis[i] = 0;
                    P[i] = 0;
                }
                int top = 0, cur = 1;
                while(top <= n - 2) {
                    while(deg[cur] != 1)
                        ++cur;
                    int u = cur;
                    do {
                        for(int v : G[u]) {
                            if(vis[v] == 1)
                                continue;
                            --deg[v];
                            --deg[u];
                            P[++top] = v;
                            vis[u] = 1;
                            u = v;
                            break;
                        }
                    } while(u < cur && deg[u] == 1 && top <= n - 2);
                }
                assert(P[n - 1] == n);
    

    每个点在Prufer中出现的次数+1就是其度数,叶子节点不存在于序列中。

    Prufer变无根树:每次选择一个剩余度数为1的最小的点,把这个点删除,然后把这个点和Prufer当前的点连接,然后两端度数-1。重复n-2次后,剩下两个度数为1的点,把他们连起来。

    这个也是用个堆来做最简单,或者用个指针来做也可以。

    下面把n-1位置也放上Prufer,为了统一处理,但是统计度数的时候不能算上它。

                P[n - 1] = n;
                for(int i = 1; i <= n; ++i) {
                    deg[i] = 1;
                    vis[i] = 0;
                    G[i].clear();
                }
                for(int i = 1; i <= n - 2; ++i)
                    ++deg[P[i]];
                int top = 0, cur = 1;
                while(top <= n - 2) {
                    while(deg[cur] != 1)
                        ++cur;
                    int u = cur;
                    do {
                        int v = P[++top];
                        --deg[v];
                        --deg[u];
                        G[u].eb(v);
                        G[v].eb(u);
                        u = v;
                    } while(u < cur && deg[u] == 1 && top <= n - 2);
                }
    
  • 相关阅读:
    SQL注入
    浅复制
    重构
    UML
    UML
    工业4.0
    MVC
    博客搬家(CSDN->博客园)
    BitCoin
    Java
  • 原文地址:https://www.cnblogs.com/purinliang/p/14289755.html
Copyright © 2020-2023  润新知