您的位置:首页 > 其它

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

2016-08-19 00:43 525 查看
题目链接:

  [b][b]http://codeforces.com/problemset/problem/698/B[/b][/b]

  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 200004
using namespace std;
typedef long long LL;
int cas,cass;
int n,m,lll,ans;
int root;
int a
,fa
;
int zhao(int aa)
{
if(fa[aa]==0 || fa[aa]==aa)return aa;
return (fa[aa]=zhao(fa[aa]));
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("1.txt","r",stdin);
//    freopen("2.txt","w",stdout);
#endif
int 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;
}
/*
//

//
*/


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: