Fix a Tree

`这里写图片描述

主要有三个步骤 1、确定根节点root2、分解环 3 连接子树

  1明确是否有可行根节点,有随便找一个;没有:从环中招一个

  2为了操作方便,使用并查集寻找环,并将找到第一个环的任意一个节点作为根节点。

 3 在确定了根节点之后,如果遇到其他可行根节点,直接连接到已确定根节点即可,就是连接子树的操作。
  
 用t数组来prime找环,依此修改tree数组 

这里写代码片
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int tree[200020],t[200020];
int findroot(int x)
{
    return x==t[x]?x:t[x]=findroot(t[x]);
}
void prime(int x,int y)
{
    int fx=findroot(x);
    int fy=findroot(y);
    t[fx]=fy;
}

int main()
{
    int n,i,j,ans,root;
    while(~scanf("%d",&n)&&n>=2)
    {
        root=-1;
        ans=0;
        for(i=1;i<=n;i++)
        {
            scanf("%d",&tree[i]);
            t[i]=i;
            if(i==tree[i])
                root=i;
        }
        for(i=1;i<=n;i++)
        {
            if(tree[i]==i&&i==root)
                continue;
            else if(tree[i]==i&&i!=root)
            {
                ans++;
                tree[i]=root;
                prime(i,root);
            }
            else if(tree[i]!=i&&findroot(tree[i])!=findroot(i))
                prime(i,tree[i]);
            else if(tree[i]!=i&&findroot(tree[i])==findroot(i))
            {
                if(root==-1)
                {
                    root=i;
                }
                tree[i]=root;
                ans++;
                prime(i,root);
            }
        }
        printf("%d\n",ans);
        for(i=1;i<=n;i++)
        {
            printf("%d",tree[i]);
            if(i!=n)printf(" ");
            else printf("\n");
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值