zoukankan      html  css  js  c++  java
  • Cogs 1070. [焦作一中2012] 玻璃球游戏 带权并查集,逆序处理

    题目: http://cojs.tk/cogs/problem/problem.php?pid=1070

    1070. [焦作一中2012] 玻璃球游戏

    ★   输入文件:marbles.in   输出文件:marbles.out   简单对比
    时间限制:1 s   内存限制:128 MB

    【问题描述】

    小x的业余生活中,有一项是玩滚玻璃球游戏。

    某天,小x想到了一种很无趣的玩法,当然,这种玩法就是为了玩看题的你们。

    小x首先建立了一个单向轨道,这个单向轨道可以抽象成一个有向图,每个顶点的出度都是1,也就是由每个点出发,只有一条边连向其他的点。

    小x的游戏最初规则是这样的:让玻璃球从某一个点出发,沿着有向边的方向,移动到它的下一个顶点,如果还能移动,就继续移动,直到没有相邻的边,当然会存在在一个环里不停运动的情况。

    为了增加难度,小x决定将游戏规则增强,他会提出一系列问题,让你回答:

    1) 格式:1 X.查询玻璃球由编号为X的点出发,最终在哪个点停下来,如果能停下来,输出最后的点的编号,如果停不下来,输出”CIKLUS”.

    2) 格式:2 X.删除由X出发的那条有向边。

    【输入】

    第一行包含一个正整数N(1<=N<=300000),表示图的顶点数。

    第二行包含由空格隔开N个正整数,第i个数表示从i顶点可以通过出边到达的定点编号,0表示该点没有出边。

    接下来的一行包含1个整数Q(1<=Q<=300000),表示询问的次数。

    再接下来Q行,每行表示一次查询,格式如题目描述。

    【输出】

    对于第1类询问,输出玻璃球停止时所在顶点编号,每行1个,按照查询的顺序输出。如果玻璃球无法停止,输出”CIKLUS”即可.

    【输入输出样例1】

    marbles.in

    marbles.out

    2 3 1 

    1 1 

    1 2 

    2 1 

    1 2 

    1 1 

    2 2 

    1 2

    CIKLUS 

    CIKLUS 

    2

    【输入输出样例2】

    marbles.in

    marbles.out

    0 3 5 3 4 

    1 1 

    1 2 

    2 4 

    1 2 

    2 3 

    1 2

    CIKLUS 

    3

    【数据范围】 

       40% 数据保证  N<=100,  Q<=1000

    题解:

    摘自liu_runda

    先处理完所有删边操作,再逆序处理所有操作(原来的删边处理时改为添边)。
    维护一个带权并查集(所谓的权就是会不会走到环路)。
    最后一个点用递归find()会爆栈,改迭代find()就可以了。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define MAXN 300010
     4 #define MAXQ 300010
     5 int end[MAXN],fh[MAXQ],x[MAXQ],ans[MAXQ],father[MAXN];
     6 bool del[MAXN],circle[MAXN];
     7 int read()
     8 {
     9     int s=0,fh=1;char ch=getchar();
    10     while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();}
    11     while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();}
    12     return s*fh;
    13 }
    14 inline int Findfather(int o)
    15 {
    16     if(o==father[o])return father[o];
    17     else
    18     {
    19         father[o]=Findfather(father[o]);
    20         circle[o]=circle[father[o]];
    21         return father[o];
    22     }
    23 }
    24 inline void ak(int aa,int bb)
    25 {
    26     int a1=Findfather(aa);
    27     int b1=Findfather(bb);
    28     if(a1!=b1)father[a1]=b1;
    29     else
    30     {
    31         circle[a1]=true;circle[b1]=true;
    32     }
    33 }
    34 int main()
    35 {
    36     freopen("marbles.in","r",stdin);
    37     freopen("marbles.out","w",stdout);
    38     int i,N,Q,lans,xx;
    39     N=read();
    40     for(i=1;i<=N;i++)end[i]=read(),father[i]=i;
    41     Q=read();
    42     for(i=1;i<=Q;i++)
    43     {
    44         fh[i]=read();x[i]=read();
    45     }
    46     memset(del,false,sizeof(del));
    47     for(i=1;i<=Q;i++)
    48     {
    49         if(fh[i]==2)del[x[i]]=true;
    50     }
    51     memset(circle,false,sizeof(circle));
    52     for(i=1;i<=N;i++)
    53     {
    54         if(del[i]==false&&end[i]!=0)ak(i,end[i]);
    55     }
    56     lans=0;
    57     for(i=Q;i>=1;i--)
    58     {
    59         if(fh[i]==1)
    60         {
    61             xx=Findfather(x[i]);
    62             if(circle[x[i]]==true)ans[++lans]=-1;
    63             else ans[++lans]=Findfather(x[i]);
    64         }
    65         else
    66         {
    67             ak(x[i],end[x[i]]);
    68         }
    69     }
    70     for(i=lans;i>=1;i--)
    71     {
    72         if(ans[i]!=-1)printf("%d
    ",ans[i]);
    73         else printf("CIKLUS
    ");
    74     }
    75     fclose(stdin);
    76     fclose(stdout);
    77     return 0;
    78 }
    View Code
  • 相关阅读:
    主成分分析(PCA)原理详解
    局部敏感哈希(Locality-Sensitive Hashing, LSH)方法介绍
    RSA算法原理(二)
    RSA算法原理(一)
    对倾斜的图像进行修正——基于opencv 透视变换
    GeoHash核心原理解析
    303. Range Sum Query
    325. Maximum Size Subarray Sum Equals k
    30. Substring with Concatenation of All Words
    76. Minimum Window Substring
  • 原文地址:https://www.cnblogs.com/Var123/p/5275671.html
Copyright © 2011-2022 走看看