2043. 猴子

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

【题目描述】

有n只猴子,第一只尾巴挂在树上,剩下的n-1只,要么被其他的猴子抓住,要么抓住了其他的猴子,要么两者均有。当然一只猴子最多抓两只另外的猴子,因为只有两只猴爪子嘛。现在给出这n只猴子抓与被抓的信息,并且在某个时刻可能某只猴子会放掉它左手或右手的猴子,导致某些猴子落在地上。求每只猴子落地的时间。

【输入格式】

第一行两个n,m,表示有n只猴子,并且总时间为m-1.

接下来n行,描述了每只猴子的信息,每行两个数,分别表示这只猴子左手和右手抓的猴子的编号,如果是-1,表示该猴子的那只手没抓其他的猴子。

再接下来M行,按时间顺序给出了一些猴子放手的信息,第1+n+i行表示i-1时刻某只猴子的放手信息,信息以两个数给出,前者表示放手的猴子的编号,后者表示其放的是哪只手,1左2右。

【输出格式】

共输出n行,第i行表示第i只猴子掉落的时刻,若第i只猴子道M-1时刻以后还没掉落,就输出-1。

【样例输入】

3 2

-1 3

3 -1

1 2

1 2

3 1

【样例输出】

-1

1

1

【提示】

n<=200000,m<=400000

【来源】

在此键入。

思路:

  逆向并查集~;

  这个题仔细读读可以发现这群猴子不按套路抓尾巴;

  可能一只猴子的尾巴会被很多只猴子抓;

  所以,这个题就成为了一个判断每个时间点连通性的问题;

  判断图的联通性自然是用并查集呀;

  但是,,,这个题貌似直接搞并查集不可行;

  所以,,要加一点点乱搞的操作;

  逆向并查集;

  我们读入每个猴子的左右手抓的尾巴(建图);

  然后,开始放手(删边);

  放手的同时,把放手的操作记录下来;

  然后,开始从第m-1秒到第0秒把放手的边加回去;

  没加一条边就通过并查集判断一下图的联通性;

  当当前块与1号联通时,就记录time;

  怎么记录time呢?略略恶心,,就不讲了,,可以去看看我的代码(直白如话);

  最后输出;

  轻松ac;

来,上代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> #define maxn 200005 using namespace std; struct NodeType {
int l,r; bool li,ri;
};
struct NodeType node[maxn<<]; struct EdgeType {
int to,next;
};
struct EdgeType edge[maxn<<]; int if_z,n,m,f[maxn],head[maxn],Time[maxn];
int cnt,do_s[maxn<<],do_w[maxn<<]; char Cget; bool if_[maxn],did[maxn]; inline void read_int(int &now)
{
now=,if_z=,Cget=getchar();
while(Cget>''||Cget<'')
{
if(Cget=='-') if_z=-;
Cget=getchar();
}
while(Cget>=''&&Cget<='')
{
now=now*+Cget-'';
Cget=getchar();
}
now*=if_z;
} inline void edge_add(int from,int to)
{
cnt++;
edge[cnt].to=to;
edge[cnt].next=head[from];
head[from]=cnt;
} int find(int x)
{
if(x==f[x]) return x;
f[x]=find(f[x]);
return f[x];
} void search(int now)
{
did[now]=true;
if(node[now].l!=-&&node[now].li)
{
int x=find(now),y=find(node[now].l);
if(x>y) swap(x,y);
if(x!=)
{
edge_add(x,y);
edge_add(y,x);
}
f[y]=x;
if(!did[node[now].l]) search(node[now].l);
}
if(node[now].r!=-&&node[now].ri)
{
int x=find(now),y=find(node[now].r);
if(x>y) swap(x,y);
if(x!=)
{
edge_add(x,y);
edge_add(y,x);
}
f[y]=x;
if(!did[node[now].r]) search(node[now].r);
}
} void search_(int now,int time_)
{
if_[now]=true;
Time[now]=time_;
for(int i=head[now];i;i=edge[i].next)
{
if(!if_[edge[i].to]) search_(edge[i].to,time_);
}
} int main()
{
freopen("monkeya.in","r",stdin);
freopen("monkeya.out","w",stdout);
memset(Time,-,sizeof(Time));
read_int(n),read_int(m);
m--;
for(int i=;i<=n;i++)
{
f[i]=i;
read_int(node[i].l);
read_int(node[i].r);
if(node[i].l!=-) node[i].li=true;
if(node[i].r!=-) node[i].ri=true;
}
for(int i=;i<=m;i++)
{
read_int(do_s[i]),read_int(do_w[i]);
if(do_w[i]==) node[do_s[i]].li=false;
else node[do_s[i]].ri=false;
}
for(int i=;i<=n;i++)
{
if(!did[i]) search(i);
}
for(int i=m;i>=;i--)
{
int x=do_s[i],y,x_,y_;
if(do_w[i]==) y=node[do_s[i]].l;
else y=node[do_s[i]].r;
if(y==-) continue;
x_=find(x),y_=find(y);
if(x_>y_) swap(x_,y_);
if(x_!=&&y_!=)
{
edge_add(x_,y_);
edge_add(y_,x_);
}
else if(x_!=&&y_==) Time[x_]=i;
else if(x_==&&y_!=) Time[y_]=i;
f[y_]=x_;
}
for(int i=;i<=n;i++)
{
if(Time[i]>=) search_(i,Time[i]);
}
for(int i=;i<=n;i++)
{
if(Time[i]<) printf("-1\n");
else printf("%d\n",Time[i]);
}
fclose(stdin);
fclose(stdout);
return ;
}

AC日记——猴子 cogs 2043的更多相关文章

  1. AC日记——codevs1688求逆序对

    AC日记--codevs1688求逆序对 锵炬 掭约芴巷 枷锤霍蚣 蟠道初盛 到被他尽情地踩在脚下蹂躏心中就无比的兴奋他是怎么都 ㄥ|囿楣 定要将他剁成肉泥.挫骨扬灰跟随着戴爷这么多年刁梅生 圃鳋 ...

  2. 洛谷 P1653 == COGS 2043 猴子

    P2107 可爱的猴子 时间限制:1000MS  空间限制:65535KB 问题描述: 树上有n只猴子.它们编号为 1 到n.1 号猴子用它的尾巴勾着树枝.剩下的猴子都被其他的猴子用手抓着.每只猴子的 ...

  3. AC日记——[NOIP2015]运输计划 cogs 2109

    [NOIP2015] 运输计划 思路: 树剖+二分: 代码: #include <cstdio> #include <cstring> #include <iostrea ...

  4. AC日记——[WC2013]糖果公园 cogs 1817

    [WC2013]糖果公园 思路: 带修改树上莫队(模板): 来,上代码: #include <cmath> #include <cstdio> #include <cst ...

  5. AC日记——[国家集训队2011]旅游(宋方睿) cogs 1867

    [国家集训队2011]旅游(宋方睿) 思路: 树链剖分,边权转点权: 线段树维护三个东西,sum,max,min: 当一个区间变成相反数时,sum=-sum,max=-min,min=-max: 来, ...

  6. AC日记——[国家集训队2010]小Z的袜子 cogs 1775

    [国家集训队2010]小Z的袜子 思路: 传说中的莫队算法(优雅的暴力): 莫队算法是一个离线的区间询问算法: 如果我们知道[l,r], 那么,我们就能O(1)的时间求出(l-1,r),(l+1,r) ...

  7. AC日记——[ZJOI2009]假期的宿舍 cogs 1333

    1333. [ZJOI2009] 假期的宿舍 ★★☆   输入文件:zjoi09holiday.in   输出文件:zjoi09holiday.out   简单对比时间限制:1 s   内存限制:25 ...

  8. AC日记——[福利]可持久化线段树 cogs 2554

    2554. [福利]可持久化线段树 ★★☆   输入文件:longterm_segtree.in   输出文件:longterm_segtree.out   简单对比时间限制:3 s   内存限制:2 ...

  9. AC日记——[网络流24题]骑士共存 cogs 746

    746. [网络流24题] 骑士共存 ★★☆   输入文件:knight.in   输出文件:knight.out   简单对比时间限制:1 s   内存限制:128 MB 骑士共存问题 «问题描述: ...

随机推荐

  1. rest_framework之status HTTP状态码

    Django Rest Framework有一个status.py的文件 通常在我们Django视图(views)中,HTTP状态码使用的是纯数字,像400,404,200,304等,并不是那么很好理 ...

  2. linux时区

    1. UTC时区切换到CST 时区# echo "export TZ='Asia/Shanghai'" >> /etc/profile # cat /etc/profi ...

  3. VNC远程登录端使用经验之一

    1.vnc/xmanager都是经常用的远程登录软件.vnc有个缺点就是他的进程不会自动退出比如如果开了PID1再去开PID2...PIDn.那么前面的PIDn-1个进程就会一直运行如果不手动kill ...

  4. 4.layhm框架初始化准备Init

    hm\core\Boot 里 Boot 里run() 自动开起session 设置时区 <?php /** * Created by Haima. * Author:Haima * QQ:228 ...

  5. OpenCV编译 Make出错 recipe for target 'modules/imgproc/CMakeFiles/opencv_test_imgproc.dir/all' failed

    OpenCV编译  Make出错 recipe for target 'modules/imgproc/CMakeFiles/opencv_test_imgproc.dir/all' failed 添 ...

  6. Java-basic-4-数据类型

    Number类 装箱:将内置数据类型作为包装类对象使用:拆箱:相反 public class test{ public static void main(String args[]) { // box ...

  7. python列表中的深浅copy

    列表中的赋值和平常的赋值是不一样的,看下面的代码: In [1]: a = 1 In [2]: b = a In [3]: a Out[3]: 1 In [4]: b Out[4]: 1 In [5] ...

  8. python模块之shutil和zipfile

    shutil 模块 高级的 文件.文件夹.压缩包 处理模块 shutil.copyfileobj(fsrc, fdst[, length])将文件内容拷贝到另一个文件中 import shutil s ...

  9. hdu-2063 过山车(二分图)

    Time limit1000 ms Memory limit32768 kB RPG girls今天和大家一起去游乐场玩,终于可以坐上梦寐以求的过山车了.可是,过山车的每一排只有两个座位,而且还有条不 ...

  10. Linux学习-开机过程的问题解决

    忘记 root 密码的解决之道 新版的 systemd 的管理机制中,默认的 rescue 模式是无法直接取得 root 权限的喔!还是得要 使用 root 的密码才能够登入 rescure 环境.没 ...