• Codeforces Round #363 Fix a Tree(树 拓扑排序)


    先做拓扑排序,再bfs处理

    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<map>
    #include<stack>
    #include<queue>
    #include<vector>
    #include<cmath>
    #include<utility>
    using namespace std;
    typedef long long LL;
    const int N = 210008, INF = 0x3F3F3F3F;
    #define MS(a, num) memset(a, num, sizeof(a))
    #define PB(A) push_back(A)
    #define FOR(i, n) for(int i = 0; i < n; i++)
    bool vis[N];
    struct Node{
        int to,next;
    }edge[N];
    int head[N], tot, n,m,indeg[N];
    int fa[N];
    void init(){
        memset(head, -1sizeof(head));
        memset(indeg, 0sizeof(indeg));
        tot = 0;
    }
    void add(int u, int to){
        indeg[to]++;
        edge[tot].to=to;
        edge[tot].next=head[u];
        head[u]=tot++;
    }
    void Topsort(){
    stack <int> st;
        for(int i = 1;i<=n; i++) {
            if(indeg[i]==0) {
                st.push(i);
            }
        }
        while(!st.empty()){
            int cur = st.top();
            st.pop();
            vis[cur] = 1;
            for(int i = head[cur]; i != -1; i = edge[i].next){
                int to= edge[i].to;
                indeg[to]--;
                if(!indeg[to]){
                    st.push(to);
                }
            }
        }
    }

    void bfs(int u){
        queue<int> q;
        q.push(u);
        vis[u]  =1;
        while(!q.empty()){
                int u = q.front();
                q.pop();
               for(int i= head[u]; i != -1; i = edge[i].next){
                    int to = edge[i].to;
                    if(!vis[to]){
                        vis[to] = 1;
                        q.push(to);
                    }
                }
        }
    }
    int main(){
        cin>>n;
        MS(vis, 0);
        init();
        for(int i = 1;i <= n ;i++){
            int u;
            scanf("%d", &u);
            fa[i] = u;
            add(i, u);
        }
        Topsort();
        int v = 0;
        for(int i = 1;i <= n; i++){
            if(fa[i] == i){
                vis[i] = 1;
                v = i;
                break;
            }
        }
        if(v == 0){
            for(int i = 1;i <= n; i++){
                if(!vis[i]){
                    fa[i] = i;
                    v = i;
                    break;
                }
            }
        }

        int cnt = 0;
        for(int i =1; i <= n; i++){
            if(!vis[i]){
                fa[i] = v;
                cnt++;
                bfs(i);
            }
        }
        cout<<cnt<<' ';
        cout<<fa[1];
        for(int i  = 2;i <= n;i++){
            printf(" %d", fa[i]);
        }
        return 0;

    } 

  • 相关阅读:
    【Gerrit】重磅! 2.x 版本升级到 3.x 版本
    【Linux】参数传递之xargs
    Sqlserver账号对应数据库
    限流:计数器、漏桶、令牌桶 三大算法的原理与实战(史上最全)
    C# 运行在ubuntu, linux系统,在linux系统使用HslCommunication组件,.net core发布到ubuntu系统
    使用nmap命令监控远程服务器指定端口状态
    MySQL使用脚本进行整库数据备份【表(结构+数据)、视图、函数、事件】
    MySQL自定义函数与存储过程的创建、使用、删除
    vue响应式的原理
    浏览器渲染机制
  • 原文地址:https://www.cnblogs.com/IMGavin/p/5703612.html
Copyright © 2020-2023  润新知