JZOJ 3875 星球联盟
【问题描述】
在遥远的 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 星球联盟的更多相关文章
- bzoj4998 星球联盟
bzoj4998 星球联盟 原题链接 题解 先按照输入顺序建一棵树(森林),然后用一个并查集维护联盟的关系,对于不是树上的边\(a-b\),就把\(a-lca(a,b),b-lca(a,b)\)全部合 ...
- [jzoj]3875.【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)
Link https://jzoj.net/senior/#main/show/3875 Problem 在遥远的S星系中一共有N个星球,编号为1…N.其中的一些星球决定组成联盟,以方便相互间的交流. ...
- BZOJ4998星球联盟——LCT+并查集(LCT动态维护边双连通分量)
题目描述 在遥远的S星系中一共有N个星球,编号为1…N.其中的一些星球决定组成联盟,以方便相互间的交流.但是,组成 联盟的首要条件就是交通条件.初始时,在这N个星球间有M条太空隧道.每条太空隧道连接两 ...
- 【刷题】BZOJ 4998 星球联盟
Description 在遥远的S星系中一共有N个星球,编号为1-N.其中的一些星球决定组成联盟,以方便相互间的交流.但是,组成联盟的首要条件就是交通条件.初始时,在这N个星球间有M条太空隧道.每条太 ...
- 【bzoj4998】星球联盟 LCT+并查集
题目描述 在遥远的S星系中一共有N个星球,编号为1…N.其中的一些星球决定组成联盟,以方便相互间的交流.但是,组成联盟的首要条件就是交通条件.初始时,在这N个星球间有M条太空隧道.每条太空隧道连接两个 ...
- 【NOIP2017练习&BZOJ4998】星球联盟(强联通分量,并查集)
题意: 在遥远的S星系中一共有N个星球,编号为1…N.其中的一些星球决定组成联盟,以方便相互间的交流. 但是,组成联盟的首要条件就是交通条件.初始时,在这N个星球间有M条太空隧道.每条太空隧道连接两个 ...
- 【JZOJ3875】【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)
fg 在遥远的S星系中一共有N个星球,编号为1-N.其中的一些星球决定组成联盟,以方便相互间的交流. 但是,组成联盟的首要条件就是交通条件.初始时,在这N个星球间有M条太空隧道.每条太空隧道连接两个星 ...
- 【BZOJ4998】星球联盟
题解: 应该还是比较水的 首先很容易发现的就是两个点一旦联通他们就永远联通了 所以联通之后我们就把他们之间缩成一个点
- 【bzoj4998】星球联盟(并查集+边双)
题面 传送门 题解 总算有自己的\(bzoj\)账号啦! 话说这题好像\(Scape\)去年暑假就讲过--然而我到现在才会-- \(LCT\)什么的跑得太慢了而且我也不会,所以这里是一个并查集的做法 ...
随机推荐
- Visual Studio 调试 —— 附加到进程(远程服务器)
一般在部署环境下不会有 Visual Studio 开发工具的,所以需要有 Remote Debugger(远程调试器) 才可以进行远程调试. Remote Debugger 获取 方法一:Visua ...
- Python(Head First)学习笔记:一
目录: 1 认识Python:Python的特点.安装.开发环境搭建 2 共享代码:连接共享社区.语法.函数.技巧 3 文件与异常:调试.处理错误.迭代.改进.完善 4 持久存储:文件存储.读写 5 ...
- 基础知识:什么是SNMP
简单网络管理协议(SNMP) 是专门设计用于在 IP 网络管理网络节点(服务器.工作站.路由器.交换机及HUBS等)的一种标准协议,它是一种应用层协议. SNMP 使网络管理员能够管理网络效能,发现并 ...
- Cabloy-CMS:动静结合,解决Hexo痛点问题
介绍 Cabloy-CMS是什么 Cabloy-CMS是基于CabloyJS全栈业务开发框架开发的"动静结合"的CMS,可以快速构建企业网站.博客.社区.商城等Web应用. 在线演 ...
- 中国知网(CNKI)验证码识别
中国知网(CNKI)是最重要的中文学术资源数据库,收录绝大多数中文学术刊物.我们可以检索论文,也可以导出检索结果前6000条论文的题录数据. 在CNKI检索结果翻页10次以上,用户需要手动输入验证码才 ...
- MOOC C++笔记(二):类和对象基础
第二周:类和对象基础 面向对象程序设计的四个基本特点 抽象.封装.继承.多态. 面向对象程序设计的过程 1.从客观事物抽象出类 抽象出的事物带有成员函数与成员变量(类似于带函数的结构体) 成员变量和成 ...
- [CUDA] 00 - GPU Driver Installation & Concurrency Programming
前言 对,这是一个高大上的技术,终于要做老崔当年做过的事情了,生活很传奇. 一.主流 GPU 编程接口 1. CUDA 是英伟达公司推出的,专门针对 N 卡进行 GPU 编程的接口.文档资料很齐全,几 ...
- 基于docker构建测试环境
目录 0x01介绍 0x02 镜像基本操作 0x03 容器基本操作 0x04 容器的修改与保存 0x05 使用Dockerfile定制镜像 0x01介绍 Docker 是一个开源的应用容器引擎,基于 ...
- (java实现)顺序表-ArrayList
什么是顺序表 顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构. 在使用顺序表存储数据前,会先申请一段连续的内存空间(即数组),然后把数组依次存入 ...
- Hadoop源代码点滴-文件系统HDFS
HDFS是Hadoop集群的文件系统,这是一种分布(distributed).容错(fault tolerant)的文件系统 所谓分布,是说整个文件系统的内容并非集中存储在一台或几台“文件服务器上”, ...