zoukankan      html  css  js  c++  java
  • 游戏「并查集」

    游戏「并查集」

    题目描述

    Mirko和 Slavko 爱玩弹球戏。在一个令人激动的星期五,Mirko 和 Slavko 玩了一把弹球游戏。Mirko 构建一个有向图,所有顶点最多有 1 条出边。弹球从 1个顶点出发可以沿着一条边移动到它的邻接点,只要它存在,而且它会继续移动到后者的邻接点去,直到最后到达一个找不到出边的顶点才停下来。如果不存在这样的点,弹球可能无限运动下去。
    为了确信 Slavko理解游戏的规则,Mirko 将发起一系列询问,询问的类型如下:

      1 X:除非弹球陷入循环,弹球从 X出发,最终将在哪个点停下来。
      2 X:删除 X的出边(保证该边总是存在)
      注意:询问是按顺序执行的。
    

    输入

    第一行包含一个正整数 N(1<=N<=300000),表示图的定点数。
    第二行包含由空格隔开 N个正整数,第 i 个数表示从 i 顶点可以通过出边到达的定点编号。0表示该点没有出边。
    接下来的一行包含 1个整数 Q(1<=Q<=300000),表示询问的次数。格式如上所示。

    输出

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

    样例输入

    2 3 1
    7
    1 1
    1 2
    2 1
    1 2
    1 1
    2 2
    1 2
    

    样例输出

    CIKLUS
    1
    1
    2
    

    思路分析

    • 因为每个节点都只有一条出边,所以我们可以考虑并查集,并查集的祖先节点即为断点。
    • 针对有环的情况,我们只需要记录一下跑的次数,若大于n则说明存在环
    • 这题的关键在于删边这里,我们使用倒序并查集(离线操作),另开一个数组记录删边前的状态,逐步复原即可

    代码

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    const int maxn = 3e5+10;
    int f[maxn],ff[maxn],a[maxn][2],n; //ff数组记录删边前的状态
    int find(int x,int Clock){
    	if(Clock>n)return f[x] = 0; //有环
    	if(x==f[x])return x;
    	return f[x] = find(f[x],Clock+1);
    }
    int main(){
    	scanf("%d",&n);
    	for(int i = 1;i <= n;i++)f[i] = i;
    	for(int i = 1;i <= n;i++){
    		int x;scanf("%d",&x);
    		if(x)f[i] = ff[i] = x;
    	}
    	int q;scanf("%d",&q);
    	for(int i = 1;i <= q;i++){
    		scanf("%d%d",&a[i][0],&a[i][1]); //操作种类和对象一并记录
    		if(a[i][0]==2){
    			f[a[i][1]] = a[i][1];
    		}
    	}
    	for(int i = q;i >= 1;i--){ //倒序处理,保证前面的删边操作不会对前面的查询造成影响
    		if(a[i][0]==1){
    			a[i][1] = find(a[i][1],0); //正常查询
    		}
    		else f[a[i][1]] = ff[a[i][1]]; //复原
    	}
    	for(int i = 1;i <= q;i++){
    		if(a[i][0]==1){
    			if(a[i][1])printf("%d
    ",a[i][1]);
    			else printf("CIKLUS
    "); //a[i][1]为0说明有环
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    简单计算器--hdu1237(栈的运用)
    Bone Collector
    Red and Black---hdu1312(dfs)
    RTMP规范简单分析
    FFMPEG中最关键的结构体之间的关系
    面向对象与形而上学
    洛谷 P2913 [USACO08OCT]车轮旋转Wheel Rotation
    洛谷 P1889 士兵站队
    洛谷 P1885 Moo
    洛谷 P1683 入门
  • 原文地址:https://www.cnblogs.com/hhhhalo/p/13324391.html
Copyright © 2011-2022 走看看