• 1463E.Plan of Lectures(缩点+拓扑排序)


    题意

    给出一棵树,询问这颗树的一个拓扑序,使得给出的k个点对在拓扑序里相邻。

    题解

    用缩点处理每个点对,然后对缩点后的图做拓扑排序即可。

    需要保证的是k个点对形成的图是若干条链,这里的判断写的有点乱。

    //给出一个有向图
    //求一个拓扑序
    //同时k条边需要满足相邻访问
    
    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=3e5+100;
    vector<int> g[maxn];
    int n,k;
    int p[maxn];
    int nxt[maxn],in[maxn],pos[maxn];
    int dfn[maxn],tot,inDegree[maxn];
    void topOrder () {
        queue<int> q;
        for (int i=1;i<=n;i++) {
            if (pos[i]==i&&inDegree[i]==0) {
                q.push(i); 
            }
        }
        while (q.size()) {
            int u=q.front();
            q.pop();
            int tt=u;
            while (tt) {
                dfn[++tot]=tt;
                tt=nxt[tt];
            }
            for (int v:g[u]) if (--inDegree[v]==0) {
                q.push(v);
            }
        }
    }
    int h[maxn];
    int main () {
        int rt;
        scanf("%d%d",&n,&k);
        for (int i=1;i<=n;i++) scanf("%d",p+i);
        for (int i=1;i<=k;i++) {
            int x,y;
            scanf("%d%d",&x,&y);
            if (nxt[x]) {
                return printf("0"),0;
            }
            if (in[y]) {
                return printf("0"),0;
            }
            nxt[x]=y;
            in[y]++;
        }
        for (int i=1;i<=n;i++) {
            if (pos[i]) continue;
            if (in[i]) continue;
            int u=i;
            h[u]=1;
            while (u) {
                pos[u]=i;
                if (nxt[u]&&h[nxt[u]]) return printf("0"),0;
                if (nxt[u]) h[nxt[u]]=h[u]+1;
                u=nxt[u];
            }
        }
        //for (int i=1;i<=n;i++) printf("%d ",pos[i]);
        //printf("
    ");
        for (int i=1;i<=n;i++) {
            if (!p[i])
                rt=i;
            else if (pos[p[i]]==pos[i]) {
                if (h[i]<h[p[i]]) return printf("0"),0;
                continue;
            }
            else
                g[pos[p[i]]].push_back(pos[i]),inDegree[pos[i]]++;
        }
        //for (int i=1;i<=n;i++) if (pos[i]==i) printf("%d %d
    ",i,inDegree[i]);
        topOrder();
        if (tot<n) return printf("0"),0;
        for (int i=1;i<=n;i++) printf("%d ",dfn[i]);
    } 
  • 相关阅读:
    html页面3秒后自动跳转的方法有哪些
    web前端教程之javascript创建对象的方法
    想学好web前端,需要看哪些书籍
    码农只能干到30岁的说法可信吗?
    不管你以后写不写JS,都应该学会这种思考方式
    Python基础知识之排序法
    input和textarea修改placeholder颜色和字号
    关于IE和Firefox兼容性问题及解决办法
    vue-cli构建vue项目
    js 小数取整的函数
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/14340212.html
Copyright © 2020-2023  润新知