[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. Python3 urlparse

    >>> from urllib.parse import urlparse >>> o = urlparse('http://www.cwi.nl:80/%7Egu ...

  2. HDU1213:How Many Tables(并查集)

    How Many Tables Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  3. HLPP

    LOJ 最大流加强版 #include <bits/stdc++.h> const int inf=0x7fffffff; const int maxn=1210; const int m ...

  4. Windows2008 – Task Scheduler – ‘Action “C:\Windows\SYSTEM32\cmd.exe” with return code 1’

    Remediation Edit Task Let us make the necessary changes, which is to specify the Start folder. Here ...

  5. Java Web转发和重定向问题

    0x01:转发情况.转发过程中,只请求一次,request对象设置了之后会一直存在,直到下一次请求. 0x02:重定向情况.会发生两次请求,如果设置了request对象,那么重定向之后,request ...

  6. 解决在ios下不能自动播放音频的问题

    在ios下面是不允许自动播放音频这个操作的,不过我们可以使用微信提供的sdk来做到自动播放音乐的功能 wx.ready(()=>{}) 引入微信的sdk,之后在回调函数里面执行主动触发背景音乐播 ...

  7. classList详解,让你的js方便地操作DOM类

    在此之前,jQuery的hasClass.addClass.removeClass我们已经再熟悉不过了,然而我们并不会在每一个项目中都会去使用 jQuery或者Zepto,譬如在移动端的网页中,考虑到 ...

  8. hdu1527取石子游戏---(威佐夫博弈)

    感谢 http://www.cnblogs.com/yuyixingkong/p/3362476.html 取石子游戏 Time Limit: 2000/1000 MS (Java/Others)   ...

  9. bzoj 3212 线段树

    裸的线段树 /************************************************************** Problem: User: BLADEVIL Langua ...

  10. git放弃本地commit,未push

    如果不小心commit了一个不应该commit的修改,但是还没有push,想撤销那个commit. 步骤: a) git log:获取commit id: b) git reset --hard co ...