【问题描述】
在遥远的 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. 【Offer】[32] 【从上到下打印二叉树】

    题目描述 思路分析 测试用例 Java代码 代码链接 题目描述 不换行:从上到下打印出二叉树的每个节点,同层的节点按照从左到右的顺序打印.例如,输入下图的二叉树,则依次打印出8,6,10,5,7,9, ...

  2. 当React开发者初次走进React-Native的世界

    RN千机变 1.技术体系问题 RN和React共用一套抽象层,相对于前端,RN其实更接近Node的运行环境 ReactNative =React +IOS +Android 看RN文档时,我会发现入门 ...

  3. MySQL二进制日志挖掘器BinlogMiner 1.0发布了。

    MySQL从2014年开始超越SQL Server, 占据DB-Engines数据库流行度排行榜第二名, 是一种非常流行的关系型数据库, 特别是在互联网领域, 是一种应该掌握的数据库系统.最近在学My ...

  4. .netcore 使用阿里云短信

    准备工作 阿里云上申请短信服务 创建短信应用.签名.短信模板并申请审核,如果审核不通过,接口是调不通的. 配置专门用来发短信的accessKeyId和 accessKeySecret 开始开发 下载安 ...

  5. java架构之路-(源码)mybatis基本使用

    我们今天先来简单了解一下我们持久层框架,mybatis的使用.而且现在的注解成为趋势,我主要说一下注解方向的使用吧(配置文件也会说) 从使用角度只要是三个部分,mybatis-config.xml,m ...

  6. 解决安装flask库不成功

    Python中使用python -m pip install --upgrade pip升级pip时老是不成功   场景 在使用python -m pip install --upgrade pip进 ...

  7. Google、百度搜索引擎高级应用6/15

    不得不知道的搜索技巧.

  8. Docker常用命令小记

    除了基本的docker pull.docker image.docker ps,还有一些命令及参数也很重要,在此记录下来避免遗忘. 环境信息 以下是本次操作的环境: 操作系统:CentOS Linux ...

  9. 脱离脚手架来配置、学习 webpack4.x (二)基础搭建loader 配置 css、scss

    序 上一篇已经把基本架子搭起来了,现在来增加css.scss.自动生成html.css 提前等方面的打包.webpack 默认只能处理js模块,所以其他文件类型需要做下转换,而loader 恰恰是做这 ...

  10. uboot学习之uboot.bin的运行流程

    上篇博客:http://www.cnblogs.com/yeqluofwupheng/p/7347925.html 讲到uboot-spl的工作流程,接下来简述一下uboot.bin的工作流程,这对应 ...