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. mysql 添加数据如果数据存在就更新ON DUPLICATE KEY UPDATE和REPLACE INTO

    #下面建立game表,设置name值为唯一索引. CREATE TABLE `game` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar( ...

  2. chrome浏览器跳过(忽略)所有的js断点

    在调试程序时我们经常通过打断点的方式来跟踪代码的执行流程,所以可能会在很多时候打很多断点,当我们知道了程序大概的执行流程之后,这时候断点就不太需要了.但是我们又不想马上把所有的断点清除掉,因为我们打的 ...

  3. CentOS7.2 虚拟机网卡无法启动

    在开机之后,发现网卡没有启动起来,进行了如下操作1.ifup ens33Bringing up interface ens33: Error: Connection activation failed ...

  4. 能力不足之 根据时序图转化为Verilog代码

    不能够把时序图看的非常透彻,然后把时序图写成Verilog代码,有时候甚至搞不清楚信号之间的时序关系.

  5. redis主从+哨兵模式

    主从模式配置分为手动和配置文件两种方式进行配置,我现在有192.168.238.128(CentOS1).192.168.238.131(CentOS3).192.168.238.132(CentOS ...

  6. python numpy复制array

    numpy快速复制array 前段时间想到一个算法,需要实现array的自我复制,直接上代码,两种复制方式, 整体复制 a=[[10,10,50,50],[10,10,40,50]] np.tile( ...

  7. web开发框架tornado

    在server.py文件中 import tornado.web import tornado.ioloop import tornado.httpserver import config from ...

  8. POJ:2060-Taxi Cab Scheme(最小路径覆盖)

    传送门:http://poj.org/problem?id=2060 Taxi Cab Scheme Time Limit: 1000MS Memory Limit: 30000K Total Sub ...

  9. BZOJ 2721: [Violet 5]樱花

    (X-N)(Y-N)=N^2 #include<cstdio> using namespace std; const int mod=1e9+7; int n,cnt,isprime[10 ...

  10. PHP函数参数传递(相对于C++的值传递和引用传递)

    学语言学得比较多了,今天突然想PHP函数传递,对于简单类型(基本变量类型)和复杂类型(类)在函数参数传递时,有没有区别呢,今天测试了下: 代码如下: <?php function test($a ...