【并查集】【模拟】Codeforces 698B & 699D Fix a Tree

来源:互联网 发布:hazeover for mac 编辑:程序博客网 时间:2024/05/19 13:19

题目链接:

  http://codeforces.com/problemset/problem/699/D

题目大意:

  通过给定当前节点的父亲给你一棵有错的树,可能有多个根和环,输出改成正确的一棵树至少要修改几个节点的父亲和修改后所有点的父亲值

题目思路:

  【并查集】【模拟】

  用并查集把成环的归在一起(类似强连通分量),然后统计分量数并修改。

  第一个出现的当作根,其余的每一块连通分量都去掉一条边改为连接到根上。




////by coolxxx////<bits/stdc++.h>#include<iostream>#include<algorithm>#include<string>#include<iomanip>#include<map>#include<memory.h>#include<time.h>#include<stdio.h>#include<stdlib.h>#include<string.h>//#include<stdbool.h>#include<math.h>#define min(a,b) ((a)<(b)?(a):(b))#define max(a,b) ((a)>(b)?(a):(b))#define abs(a) ((a)>0?(a):(-(a)))#define lowbit(a) (a&(-a))#define sqr(a) ((a)*(a))#define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b))#define mem(a,b) memset(a,b,sizeof(a))#define eps (1e-8)#define J 10#define MAX 0x7f7f7f7f#define PI 3.14159265358979323#define N 200004using namespace std;typedef long long LL;int cas,cass;int n,m,lll,ans;int root;int a[N],fa[N];int zhao(int aa){if(fa[aa]==0 || fa[aa]==aa)return aa;return (fa[aa]=zhao(fa[aa]));}int main(){#ifndef ONLINE_JUDGEfreopen("1.txt","r",stdin);//freopen("2.txt","w",stdout);#endifint i,j,fx,fy;//for(scanf("%d",&cas);cas;cas--)//for(scanf("%d",&cas),cass=1;cass<=cas;cass++)while(~scanf("%d",&n))//while(~scanf("%d",&n)){mem(fa,0);ans=0;root=0;for(i=1;i<=n;i++){scanf("%d",&a[i]);if(a[i]==i)root=i;fx=zhao(a[i]);fy=zhao(i);if(fx!=fy)fa[fy]=fx;}for(i=1;i<=n;i++){fa[i]=zhao(i);if(fa[i]==i){if(!root){ans++;root=i;a[i]=i;}else if(i!=root)ans++,a[i]=root;}}printf("%d\n",ans);for(i=1;i<=n;i++)printf("%d ",a[i]);puts("");}return 0;}/*////*/


0 0
原创粉丝点击