【问题描述】
在遥远的 S 星系中一共有 N 个星球,编号为 1…N。其中的一些星球决定组成联盟,
以方便相互间的交流。
但是,组成联盟的首要条件就是交通条件。初始时,在这 N 个星球间有 M 条太空
隧道。每条太空隧道连接两个星球,使得它们能够相互到达。若两个星球属于同一个联
盟,则必须存在一条环形线路经过这两个星球,即两个星球间存在两条没有公共隧道的
路径。
为了壮大联盟的队伍,这些星球将建设 P 条新的太空隧道。这 P 条新隧道将按顺序
依次建成。一条新轨道建成后,可能会使一些星球属于同一个联盟。你的任务是计算出,
在一条新隧道建设完毕后,判断这条新轨道连接的两个星球是否属于同一个联盟,如果
属于同一个联盟就计算出这个联盟中有多少个星球。
【输入格式】
第 1 行三个整数 N,M 和 P,分别表示总星球数,初始时太空隧道的数目和即将建
设的轨道数目。
第 2 至第 M+1 行,每行两个整数,表示初始时的每条太空隧道连接的两个星球编
号。
第 M+2 行至第 M+P+1 行,每行两个整数,表示新建的太空隧道连接的两个星球编
号。这些太空隧道按照输入的顺序依次建成。
【输出格式】
输出共 P 行。如果这条新的太空隧道连接的两个星球属于同一个联盟,就输出一个
整数,表示这两个星球所在联盟的星球数。如果这条新的太空隧道连接的两个星球不属
于同一个联盟,就输出”No”(不含引号) 。
【样例 1】
alliance.in
3 2 1
1 2
1 3
2 3

alliance.out

3

alliance.in
5 3 4
1 2
4 3
4 5
2 3
1 3
4 5
2 4

alliance.out

No
3

2

5

题解:  

  这个题目,第一眼看上去就是一个双联通分量,但是很明显双联通分量,但是只能跑出40分,所以需要换思路,发现每次重构算了很多不需要算的边双联通分量,所以我们可以只关注要连边的那两个点,首先我们可以先把整个图(包括要加入的边)扣出一颗树来,为什么要想到树呢?

  因为如果把暴力进行改进把边双缩树(这一步可以不必要进行),那么显然加的边上的两点到lca的路径上的所有点都会形成一个环,那么这次询问的答案就是这个环的size,那么我们就可以把这个环缩成一个点,但怎么快速缩点?将所以的点用并查集的方式指向lca就可以了,答案就是lca的size(在并查集中的)。

代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#define MAXN 200100
using namespace std;
struct edge{
int from,to,flag,tag;
edge(){flag=,tag=;}
}ee[MAXN*];
struct e{
int first,next,to;
}a[MAXN*];
int f[MAXN],fa[MAXN],sz[MAXN],last[MAXN],dep[MAXN];
int n,m,p,num=; void addedge(int from,int to){
a[++num].to=to;
a[num].next=a[from].first;
a[from].first=num;
} int find(int x){
if(f[x]!=x) f[x]=find(f[x]);
return f[x];
} int find2(int x){
if(fa[x]!=x) fa[x]=find2(fa[x]);
return fa[x];
} void conbine(int x,int y){
int xx=find(x),yy=find(y);
if(xx!=yy) f[xx]=yy;
} void conbine2(int x,int y){
int xx=find2(x),yy=find2(y);
if(fa[xx]!=fa[yy]) {fa[xx]=yy;sz[yy]+=sz[xx];}
} void init(){
scanf("%d%d%d",&n,&m,&p);
for(int i=;i<=m;i++){
int x,y;scanf("%d%d",&x,&y);
ee[i].from=x,ee[i].to=y;
}
for(int i=;i<=p;i++){
int x,y;scanf("%d%d",&x,&y);
ee[i+m].from=x,ee[i+m].to=y,ee[i+m].tag=;
}
m+=p;
} void build(){
for(int i=;i<=n;i++) f[i]=i;
for(int i=;i<=m;i++){
int x=ee[i].from,y=ee[i].to;
if(find(x)!=find(y)){
addedge(x,y),addedge(y,x);
conbine(x,y);ee[i].flag=;
}
}
} void dfs(int now,int father){
dep[now]=dep[father]+;
last[now]=father;
for(int i=a[now].first;i;i=a[i].next){
int to=a[i].to;
if(dep[to]) continue;
dfs(to,now);
}
} int dfs1(int x,int y){
x=find2(x),y=find2(y);
if(x==y) return x;
int lca;
if(dep[x]>dep[y]){lca=dfs1(last[x],y);conbine2(x,lca);}
else {lca=dfs1(x,last[y]);conbine2(y,lca);}
return lca;
} void work(){
for(int i=;i<=n;i++) fa[i]=i;
for(int i=;i<=n;i++) sz[i]=;
for(int i=;i<=m;i++){
if(ee[i].flag){
if(ee[i].tag)
printf("No\n");
continue;
}
dfs1(ee[i].from,ee[i].to);
if(ee[i].tag) printf("%d\n",sz[find2(ee[i].from)]);
}
} int main()
{
init();
build();
for(int i=;i<=n;i++) if(!dep[i]) dfs(i,i);
work();
return ;
}

JZOJ 3875 星球联盟的更多相关文章

  1. bzoj4998 星球联盟

    bzoj4998 星球联盟 原题链接 题解 先按照输入顺序建一棵树(森林),然后用一个并查集维护联盟的关系,对于不是树上的边\(a-b\),就把\(a-lca(a,b),b-lca(a,b)\)全部合 ...

  2. [jzoj]3875.【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)

    Link https://jzoj.net/senior/#main/show/3875 Problem 在遥远的S星系中一共有N个星球,编号为1…N.其中的一些星球决定组成联盟,以方便相互间的交流. ...

  3. BZOJ4998星球联盟——LCT+并查集(LCT动态维护边双连通分量)

    题目描述 在遥远的S星系中一共有N个星球,编号为1…N.其中的一些星球决定组成联盟,以方便相互间的交流.但是,组成 联盟的首要条件就是交通条件.初始时,在这N个星球间有M条太空隧道.每条太空隧道连接两 ...

  4. 【刷题】BZOJ 4998 星球联盟

    Description 在遥远的S星系中一共有N个星球,编号为1-N.其中的一些星球决定组成联盟,以方便相互间的交流.但是,组成联盟的首要条件就是交通条件.初始时,在这N个星球间有M条太空隧道.每条太 ...

  5. 【bzoj4998】星球联盟 LCT+并查集

    题目描述 在遥远的S星系中一共有N个星球,编号为1…N.其中的一些星球决定组成联盟,以方便相互间的交流.但是,组成联盟的首要条件就是交通条件.初始时,在这N个星球间有M条太空隧道.每条太空隧道连接两个 ...

  6. 【NOIP2017练习&BZOJ4998】星球联盟(强联通分量,并查集)

    题意: 在遥远的S星系中一共有N个星球,编号为1…N.其中的一些星球决定组成联盟,以方便相互间的交流. 但是,组成联盟的首要条件就是交通条件.初始时,在这N个星球间有M条太空隧道.每条太空隧道连接两个 ...

  7. 【JZOJ3875】【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)

    fg 在遥远的S星系中一共有N个星球,编号为1-N.其中的一些星球决定组成联盟,以方便相互间的交流. 但是,组成联盟的首要条件就是交通条件.初始时,在这N个星球间有M条太空隧道.每条太空隧道连接两个星 ...

  8. 【BZOJ4998】星球联盟

    题解: 应该还是比较水的 首先很容易发现的就是两个点一旦联通他们就永远联通了 所以联通之后我们就把他们之间缩成一个点

  9. 【bzoj4998】星球联盟(并查集+边双)

    题面 传送门 题解 总算有自己的\(bzoj\)账号啦! 话说这题好像\(Scape\)去年暑假就讲过--然而我到现在才会-- \(LCT\)什么的跑得太慢了而且我也不会,所以这里是一个并查集的做法 ...

随机推荐

  1. 【Nginx】应用场景

    一.概述 二.Nginx虚拟主机配置 2.1 外网映射工具 2.2 基于虚拟主机配置域名 2.3 基于端口的虚拟主机 三.Nginx配置反向代理 3.1 反向代理的作用 3.2 反向代理的好处 3.3 ...

  2. Redis缓存穿透、缓存雪崩、并发问题分析与解决方案

    (一)缓存和数据库间数据一致性问题 分布式环境下(单机就不用说了)非常容易出现缓存和数据库间的数据一致性问题,针对这一点的话,只能说,如果你的项目对缓存的要求是强一致性的,那么请不要使用缓存.我们只能 ...

  3. WAP自助建站平台娃派宣布关闭 感谢建站之路有你的启蒙

    如题所示的这篇文章是我心血来潮在网上搜索到的,写的挺让我感同身受的,不妨先看一下原文吧. 原文 不知是偶然还是"冥冥定数",最后一次访问娃派建站(wap.ai)已有数十月之久了,突 ...

  4. ZFNet(2013)及可视化的开端

    目录 写在前面 网络架构与动机 特征可视化 其他 参考 博客:blog.shinelee.me | 博客园 | CSDN 写在前面 ZFNet出自论文< Visualizing and Unde ...

  5. 三、SpringBoot 整合mybatis 多数据源以及分库分表

    前言 说实话,这章本来不打算讲的,因为配置多数据源的网上有很多类似的教程.但是最近因为项目要用到分库分表,所以让我研究一下看怎么实现.我想着上一篇博客讲了多环境的配置,不同的环境调用不同的数据库,那接 ...

  6. NPOI导出2007格式报错:文件损坏

    这个问题,归根结底还是代码问题,如下修改了代码就可以了.左侧是会出现问题的代码,右侧是正确的代码,自己感受,我也是一口老血:

  7. [CUDA] 00 - GPU Driver Installation & Concurrency Programming

    前言 对,这是一个高大上的技术,终于要做老崔当年做过的事情了,生活很传奇. 一.主流 GPU 编程接口 1. CUDA 是英伟达公司推出的,专门针对 N 卡进行 GPU 编程的接口.文档资料很齐全,几 ...

  8. Laravel 从入门到精通 创建并运行一个新的 Laravel 项目

    创建一个新的 Laravel 项目 正如官方文档所言,有两种方式可以创建一个新的 Laravel 项目,这两种创建方式都是从命令行执行的:第一种是通过全局的 Laravel 安装器,另一种是通过 Co ...

  9. redis 主从复制和哨兵模式(二)

    Redis 主从复制 为了分担单机 redis 的数据服务压力,需要进行读写分离,所以搭建 redis 的主从结构,主节点负责写,从节点负责读,主节点定期把数据同步到从节点. 配置主从 # 配置文件中 ...

  10. shell脚本一键部署lvs+keepalived

    环境 两个调度器dr1.dr2,两台真实机rs1.rs2.两台真实机安装httpd,并编辑主页内容用于验证 vip="192.168.132.250"dr1="192.1 ...