[HDU6271]Master of Connected Component

题目大意:

给出两棵\(n(n\le10000)\)个结点的以\(1\)为根的树\(T_a,T_b\),和一个拥有\(m(m\le10000)\)个结点的图\(G\)。\(T_a,T_b\)的每一个结点上都有一个信息,表示\(G\)中的一条边\((u_i,v_i)\)。对于\(i\in[1,n]\),询问从\(T_a\)和\(T_b\)上分别取出链\(1\sim i\),将链上的信息所表示的边加入\(G\)中后,\(G\)中共有多少连通块。

思路:

对于\(T_a\)分块,对于\(T_a\)中的每一块,在\(T_b\)上DFS,若当前结点是\(T_a\)当前块内结点,则暴力加入\(T_b\)中所需要的边进行统计。加边、删边操作用栈记录并查集合并情况,并查集只按秩合并,不路径压缩,实现可拆分并查集。时间复杂度\(O(n\sqrt n\log n)\)。

源代码:

#include<cmath>
#include<stack>
#include<cstdio>
#include<cctype>
#include<vector>
#include<numeric>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
constexpr int N=10001;
int n,m,lim,ans[N],par[2][N],dep[N],dfn[N];
std::pair<int,int> w[2][N];
std::vector<int> e[2][N];
inline void clear() {
dfn[0]=0;
for(register int t=0;t<2;t++) {
for(register int i=1;i<=n;i++) {
e[t][i].clear();
e[t][i].shrink_to_fit();
}
}
std::fill(&ans[1],&ans[n]+1,0);
}
int top;
std::pair<int*,int> stack[N*4];
inline void push(int &x) {
stack[++top]={&x,x};
}
inline void back(const int &tmp) {
for(;tmp<top;top--) {
*stack[top].first=stack[top].second;
}
}
class DisjointSet {
private:
int anc[N],size[N];
int find(const int &x) {
return x==anc[x]?x:find(anc[x]);
}
public:
void reset() {
std::iota(&anc[1],&anc[m+1],1);
std::fill(&size[1],&size[m+1],1);
}
void merge(const int &x,const int &y) {
int p=find(x),q=find(y);
if(p==q) return;
if(size[p]>size[q]) std::swap(p,q);
push(anc[p]);
push(size[q]);
anc[p]=q;
size[q]+=size[p];
}
};
DisjointSet s;
void solve(const int &x,const int &t) {
const int tmp=top;
s.merge(w[1][x].first,w[1][x].second);
if(ans[x]==-1&&dfn[x]>=dfn[t]) {
const int tmp=top;
for(register int y=x;y!=t;y=par[0][y]) {
s.merge(w[0][y].first,w[0][y].second);
}
ans[x]=m-top/2;
back(tmp);
}
for(auto &y:e[1][x]) {
solve(y,t);
}
back(tmp);
}
void dfs(const int &x) {
const int tmp=top;
s.merge(w[0][x].first,w[0][x].second);
dep[x]=1;
dfn[x]=++dfn[0];
for(auto &y:e[0][x]) {
dfs(y);
dep[x]=std::max(dep[x],dep[y]+1);
}
ans[x]=-1;
if(dep[x]==lim||x==1) {
solve(1,x);
dep[x]=0;
}
back(tmp);
}
int main() {
for(register int T=getint();T;T--) {
n=getint(),m=getint(),lim=sqrt(n);
for(register int t=0;t<2;t++) {
for(register int i=1;i<=n;i++) {
w[t][i]={getint(),getint()};
}
for(register int i=1;i<n;i++) {
const int u=getint(),v=getint();
par[t][v]=u;
e[t][u].push_back(v);
}
}
s.reset();
dfs(1);
for(register int i=1;i<=n;i++) {
printf("%d\n",ans[i]);
}
clear();
}
return 0;
}

[HDU6271]Master of Connected Component的更多相关文章

  1. HDU 6271 Master of Connected Component(2017 CCPC 杭州 H题,树分块 + 并查集的撤销)

    题目链接  2017 CCPC Hangzhou Problem H 思路:对树进行分块.把第一棵树分成$\sqrt{n}$块,第二棵树也分成$\sqrt{n}$块.    分块的时候满足每个块是一个 ...

  2. [LintCode] Find the Weak Connected Component in the Directed Graph

      Find the number Weak Connected Component in the directed graph. Each node in the graph contains a ...

  3. algorithm@ Strongly Connected Component

    Strongly Connected Components A directed graph is strongly connected if there is a path between all ...

  4. [LintCode] Find the Connected Component in the Undirected Graph

    Find the Connected Component in the Undirected Graph Find the number connected component in the undi ...

  5. Connected Component in Undirected Graph

    Description Find connected component in undirected graph. Each node in the graph contains a label an ...

  6. Find the Weak Connected Component in the Directed Graph

    Description Find the number Weak Connected Component in the directed graph. Each node in the graph c ...

  7. Codeforces Round #575 (Div. 3) E. Connected Component on a Chessboard(思维,构造)

    E. Connected Component on a Chessboard time limit per test2 seconds memory limit per test256 megabyt ...

  8. lintcode:Find the Connected Component in the Undirected Graph 找出无向图汇总的相连要素

    题目: 找出无向图汇总的相连要素 请找出无向图中相连要素的个数. 图中的每个节点包含其邻居的 1 个标签和 1 个列表.(一个无向图的相连节点(或节点)是一个子图,其中任意两个顶点通过路径相连,且不与 ...

  9. Codeforces 1196E. Connected Component on a Chessboard

    传送门 注意到棋盘可以看成无限大的,那么只要考虑如何构造一个尽可能合法的情况 不妨假设需要的白色格子比黑色格子少 那么容易发现最好的情况之一就是白色排一排然后中间黑的先连起来,剩下黑色的再全部填白色周 ...

随机推荐

  1. bzoj 1201[HNOI2005]数三角形 1202 [HNOI2005]狡猾的商人 暴力 权值并查集

    [HNOI2005]数三角形 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 349  Solved: 234[Submit][Status][Disc ...

  2. import pymongo exceptions.ImportError: No module named pymongo

    最近用Scrapy写爬虫,将爬取的数据存入Mongodb中,使用的是pymongo这个库,但是运行的时候报错如标题所示 搜了好多网站包括stackoverflow都没有解决,后来发现自己用的是虚拟环境 ...

  3. oracle11g 使用数据泵导出导入数据

    终于搞定了 快写个笔记 记录下. 删除用户的时候提示已经登录了不能删除,这个需要把登录的session结束掉. select username,sid,serial# from v$session w ...

  4. MyEclipse中代码提醒功能

    一:最近仔细研究了下spring mvc中的代码,自己在配置文件哪里来时出现问题,没有提醒,只好自己搜了下有关的信息.如下 window--->preferences---->java-- ...

  5. 【Foreign】采蘑菇 [点分治]

    采蘑菇 Time Limit: 20 Sec  Memory Limit: 256 MB Description Input Output Sample Input 5 1 2 3 2 3 1 2 1 ...

  6. bzoj2811 [Apio2012]Guard

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2811 [题解] 首先我们先把没看到忍者的段去掉,可以用线段树做. 如果剩下的就是K,那么特判 ...

  7. 51nod 最大M子段和系列

    1052 最大M子段和 N个整数组成的序列a[1],a[2],a[3],…,a[n],将这N个数划分为互不相交的M个子段,并且这M个子段的和是最大的.如果M >= N个数中正数的个数,那么输出所 ...

  8. Linux : 多线程下载工具: axel

    wget 应该是最常用的下载工具了,但是其不支持多线程下载. axel 安装 epel 源有 axel 的二进制包,可以使用 yum 安装. yum install epel-release yum ...

  9. C++ 头文件保护符

    头文件保护符有什么作用? 在C++中我们写头文件时经常需要#include来包含其他头文件.头文件定义的实体经常使用其他头文件的内容,有时候会出现一个头文件被多次包含进同一源文件. 例如:一个头文件中 ...

  10. Linux curl命令【curl】

    命令:curl 在Linux中curl是一个利用URL规则在命令行下工作的文件传输工具,可以说是一款很强大的http命令行工具.它支持文件的上传和下载,是综合传输工具,但按传统,习惯称url为下载工具 ...