先做拓扑排序,再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 = , 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, -, sizeof(head));
    memset(indeg, , sizeof(indeg));
    tot = ;
}
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 = ;i<=n; i++) {
        if(indeg[i]==) {
            st.push(i);
        }
    }
    while(!st.empty()){
        int cur = st.top();
        st.pop();
        vis[cur] = ;
        for(int i = head[cur]; i != -; 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]  =;
    while(!q.empty()){
            int u = q.front();
            q.pop();
           for(int i= head[u]; i != -; i = edge[i].next){
                int to = edge[i].to;
                if(!vis[to]){
                    vis[to] = ;
                    q.push(to);
                }
            }
    }
}
int main(){
    cin>>n;
    MS(vis, );
    init();
    for(int i = ;i <= n ;i++){
        int u;
        scanf("%d", &u);
        fa[i] = u;
        add(i, u);
    }
    Topsort();
    int v = ;
    for(int i = ;i <= n; i++){
        if(fa[i] == i){
            vis[i] = ;
            v = i;
            break;
        }
    }
    if(v == ){
        for(int i = ;i <= n; i++){
            if(!vis[i]){
                fa[i] = i;
                v = i;
                break;
            }
        }
    }     int cnt = ;
    for(int i =; i <= n; i++){
        if(!vis[i]){
            fa[i] = v;
            cnt++;
            bfs(i);
        }
    }
    cout<<cnt<<'\n';
    cout<<fa[];
    for(int i  = ;i <= n;i++){
        printf(" %d", fa[i]);
    }
    return ;

}

Codeforces Round #363 Fix a Tree(树 拓扑排序)的更多相关文章

  1. Codeforces Round 363 Div. 1 (A,B,C,D,E,F)

    Codeforces Round 363 Div. 1 题目链接:## 点击打开链接 A. Vacations (1s, 256MB) 题目大意:给定连续 \(n\) 天,每天为如下四种状态之一: 不 ...

  2. BZOJ_3012_[Usaco2012 Dec]First!_trie树+拓扑排序

    BZOJ_3012_[Usaco2012 Dec]First!_trie树+拓扑排序 题意: 给定n个总长不超过m的互不相同的字符串,现在你可以任意指定字符之间的大小关系.问有多少个串可能成为字典序最 ...

  3. Codeforces Round #363 (Div. 2) D. Fix a Tree —— 并查集

    题目链接:http://codeforces.com/contest/699/problem/D D. Fix a Tree time limit per test 2 seconds memory ...

  4. Codeforces Round #363 (Div. 2) 698B Fix a Tree

    D. Fix a Tree time limit per test 2 seconds memory limit per test 256 megabytes     A tree is an und ...

  5. Codeforces Round #363 (Div. 2)D. Fix a Tree(并查集)

    D. Fix a Tree time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...

  6. Codeforces Round #397 by Kaspersky Lab and Barcelona Bootcamp (Div. 1 + Div. 2 combined) E. Tree Folding 拓扑排序

    E. Tree Folding 题目连接: http://codeforces.com/contest/765/problem/E Description Vanya wants to minimiz ...

  7. Codeforces Round #363

    http://codeforces.com/contest/699 ALaunch of Collider 题意:n个球,每个球向左或右,速度都为1米每秒,问第一次碰撞的时间,否则输出-1 贪心最短时 ...

  8. Codeforces Round #363 Div.2[111110]

    好久没做手生了,不然前四道都是能A的,当然,正常发挥也是菜. A:Launch of Collider 题意:20万个点排在一条直线上,其坐标均为偶数.从某一时刻开始向左或向右运动,速度为每秒1个单位 ...

  9. Codeforces gym101755F Tree Restoration(拓扑排序)

    题意: 一棵树,给出每个点的后代们,问你这棵树是否存在,存在就给出这棵树 n<=1000 思路: 对祖先->后代建立有向图,跑拓扑排序.跑的时候不断更新父亲并判断答案的存在性,同时注意一种 ...

随机推荐

  1. 11.7---叠罗汉表演节目(CC150)

    1,牛客网第一题:这其实跟找最长递增子序列是一个东西.注意的地方是,返回的是最大的dp,而不是dp[N-1]. 答案: public static int getHeight(int[] men, i ...

  2. non

    I p(I q){r p(c((q>9?q-p(q/10):q)+'0')),q*10; }

  3. CentOS用yum安装、配置MariaDB

    .创建/etc/yum.repos.d/MariaDB.repo文件,这里用到了刚刚发布正式版的10. [mariadb] name = MariaDB baseurl = http://yum.ma ...

  4. devstack两次以上重装提高成功率的方法

    1) /opt/stack/requirements/ git reset --hard 2) rm -rf /usr/local/lib/python2.7/dist-packages/*

  5. Arp攻击实战

    hyddd原创,转载请说明出处. 现在网上很多关于ARP攻击的文章,但多数是描述其原理,少数会以某个工具作为例子展开说明,但感觉说的还是不够详细,今天写个文章以实战介绍一个叫"WinArpA ...

  6. ConsoleApplication 添加对于 System.ServiceModel.Web 引用失败(出现黄色感叹号)的解决办法

    今天在写一个WebHttpBinding的demo,再创建一个Console应用程序后,发现无法添加System.ServiceModel.Web,如图

  7. libreoffice安装

    centos7下libreoffice的安装 #下载安装包wget http://mirrors.ustc.edu.cn/tdf/libreoffice/stable/5.1.1/rpm/x86_64 ...

  8. perl的一些函数(二)

    1. tr 转换 转换不是替换(tr///==y///) tr/searchlist/replacementlist/用于查找某个一个字符串,并用replacementlist替换,可以使用正则表达式 ...

  9. BestCoder21 1002.Formula 解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5139 题目意思:给出一个数 n,求出 f(n). 可以发现有以下规律: f(1) = 1! f(2) ...

  10. String.prototype.substr()

    概述 substr() 方法返回字符串中从指定位置开始到指定长度的子字符串. 语法 str.substr(start[, length]) 参数 start 开始提取字符的位置.如果为负值,则被看作  ...