woj 1039 并查集

来源:互联网 发布:菜鸟网络借壳三泰控股 编辑:程序博客网 时间:2024/05/16 01:34

题意链接:http://acm.whu.edu.cn/learn/problem/detail?problem_id=1039

初始时每个点的父节点是自己本上,插入一个数后和他后面的一个数合并,并设置一个数更新出现值的最大位置.

#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#include <cmath>using namespace std;const int MAX=200010;int Father[MAX]; // Father[i] 表示 i 的父节点int v[MAX];//所在位置的值int cmax;//含值的最大位置int FindSet(int x){    while (x != Father[x]) x = Father[x];    return x;}void Union(int x, int y){    x = FindSet( x ); //查找 x 的祖先    y = FindSet( y ); //查找 y 的祖先    if(x == y) return ;    Father[x] = y; //合并后祖先为 y    if(y>cmax) cmax=y;}int main(){    freopen("in.txt", "r", stdin);    //freopen("out.txt", "w", stdout);    int n,i;    while(cin>>n && n)    {        cmax=1;        for(i=0;i<MAX;i++)        {            Father[i]=i; v[i]=0;        }        for(i=1;i<=n;i++)        {            int tmp,f;            cin>>tmp;            Father[tmp]=FindSet(tmp);            if(tmp== Father[tmp])            {                v[tmp]=i;                Union(tmp,tmp+1);            }            else            {                v[Father[tmp]]=i;                Union(Father[tmp],Father[tmp]+1);            }        }        if(v[cmax]==0) cmax--;            cout<<cmax<<endl;            for(i=1;i<=cmax;i++)            {                cout<<v[i];                if(i<cmax) cout<<" ";            }            cout<<endl;    }    return 0;}


原创粉丝点击