cf698B Fix a Tree

本文深入探讨了如何通过一种特定算法构建最小生成树,重点介绍了避免边形成环的策略,以及如何在森林中选择合适的根节点进行重新赋值的过程。代码示例使用C++实现,展示了Union-Find数据结构在解决此类问题中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链接

点击跳转

题解

考虑这么做:
如果这条边加入之后会成环,那我就先不要这条边,否则就要这条边

这样最后建出来是一个森林

之前被我不要的 p i p_i pi,现在要考虑重新赋值

如果原先就存在 r = p r r=p_r r=pr,那么我现在可以直接把所有待连的 i i i都连到 r r r

如果不存在这样的点,我现在需要选一个根节点,选谁呢?强行选 1 1 1会有问题,应该找第一个 p i p_i pi被我舍去的 i i i

代码

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define iinf 0x3f3f3f3f
#define linf (1ll<<60)
#define eps 1e-8
#define maxn 1000010
#define cl(x) memset(x,0,sizeof(x))
#define rep(_,__) for(_=1;_<=(__);_++)
#define em(x) emplace(x)
#define emb(x) emplace_back(x)
#define emf(x) emplace_front(x)
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
ll read(ll x=0)
{
    ll c, f(1);
    for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
    for(;isdigit(c);c=getchar())x=x*10+c-0x30;
    return f*x;
}
int n, p[maxn], root, cnt;
struct UnionFind
{
	int f[maxn];
	void init(int n)
	{
		for(auto i=1;i<=n;i++)f[i]=i;
	}
	int find(int x){return f[x]==x?x:f[x]=find(f[x]);}
	void merge(int x, int y){f[find(x)]=find(y);}
}uf;
int main()
{
    int i, j, ans=0;
    n=read();
    rep(i,n)
    {
        p[i]=read();
        if(p[i]==i)root=i;
    }
    uf.init(n);
    rep(i,n)
    {
        if(uf.find(i)==uf.find(p[i]) and i!=root)
        {
            ans++;
            if(root==0)
            {
                if(i==p[i])ans--;
                root=i;
                p[i]=i;
            }
            else p[i]=root;
        }
        uf.merge(i,p[i]);
    }
    printf("%d\n",ans);
    rep(i,n)printf("%d ",p[i]);
    return 0;
}
这是操作记录,按说明没有成功 JiuJue@DESKTOP-5ER8D0A MINGW64 /d/wwwRoot/SHARE/D-JingWaiDianShang/uni-app (master) $ git revert --no-commit b12ce7b 143c352 8eaea60 Auto-merging config/app.js CONFLICT (content): Merge conflict in config/app.js Auto-merging pages/users/login/index.vue CONFLICT (content): Merge conflict in pages/users/login/index.vue CONFLICT (modify/delete): pages/users/order_confirm/index.vue deleted in parent of b12ce7b (代码提交) and modified in HEAD. Version HEAD of pages/users/order_confirm/index.vue left in tree. CONFLICT (modify/delete): static/html/pc.html deleted in parent of b12ce7b (代码提交) and modified in HEAD. Version HEAD of static/html/pc.html left in tree. error: could not revert b12ce7b... 代码提交 hint: after resolving the conflicts, mark the corrected paths hint: with 'git add <paths>' or 'git rm <paths>' hint: Disable this message with "git config advice.mergeConflict false" JiuJue@DESKTOP-5ER8D0A MINGW64 /d/wwwRoot/SHARE/D-JingWaiDianShang/uni-app (master|REVERTING) $ git commit -m "撤销 08acc0c 之后的所有提交" error: Committing is not possible because you have unmerged files. hint: Fix them up in the work tree, and then use 'git add/rm <file>' hint: as appropriate to mark resolution and make a commit. fatal: Exiting because of an unresolved conflict. U config/app.js U pages/users/login/index.vue U pages/users/order_confirm/index.vue U static/html/pc.html JiuJue@DESKTOP-5ER8D0A MINGW64 /d/wwwRoot/SHARE/D-JingWaiDianShang/uni-app (master|REVERTING) $ git push origin master Everything up-to-date JiuJue@DESKTOP-5ER8D0A MINGW64 /d/wwwRoot/SHARE/D-JingWaiDianShang/uni-app (master|REVERTING) $ JiuJue@DESKTOP-5ER8D0A MINGW64 /d/wwwRoot/SHARE/D-JingWaiDianShang/uni-app (master|REVERTING) $ JiuJue@DESKTOP-5ER8D0A MINGW64 /d/wwwRoot/SHARE/D-JingWaiDianShang/uni-app (master|REVERTING) $ git log --oneline 8eaea60 (HEAD -> master, origin/master) 修改googel登录 143c352 代码修改提交 b12ce7b 代码提交 08acc0c fix: 佣金界面 07d2c67 fix: 佣金界面 bdf7b8e fix: 佣金界面 0987ad2 fix: 积分商品兑换取消注释 f69164e fix: 全局修改货币标识 f2d4406 fix: 接入paypal a4e1679 fix: 商品跳转链接 90ccade fix: 商品详情页布局 0528b9d fix: 商品详情页布局 507c453 fix: 页面调整 5ecc127 fix: 页面语言调整 a601cf8 fix: 首页商品 42be322 fix: 移除 30a509a fix: 分类页面 617dd9d fix: 分类页面 813aba6 fix: 添加uviewui fbcb681 fix: first commit
最新发布
03-09
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值