[jzoj]4769. 【GDOI2017模拟9.9】graph(带权并查集+分治)

版权声明:蒟蒻写的文章,能看就行了,同时欢迎大佬们指点错误 https://blog.csdn.net/Algor_pro_king_John/article/details/88649987
Problem
  • 对于一个图, 如果它的点集能被分成两个部分, 使得在原图中每一部分之间的点没有任何边相连,则该图被称为二分图。

  • 现在给定一个无向图,每次增加一条边,或者删除一条边。要求您每次判断它是不是二分图。

Data constraint
  • n , m 3 1 0 5 n,m\le 3*10^5 .
Solution
  • 补充一下题解的分治做法。实际上与线段树做法是一致的。

  • 我们把题目的给定加边删边转化成一条边存在的时间,例如一条边是第 i i 时刻加, j j 时刻减,它存在的时间就是 [ i , j 1 ] [i,j-1] .

  • 之后,我们分治时间。

  • 设当前处理到的时间区间为 [ L , R ] [L,R] ,则所有覆盖 [ L , R ] [L,R] 的边都会对当前时间区间有影响。我们把这些边用并查集处理一下。因为原图要求是二分图,实际上就是判断有没有奇环。而判奇环可以直接用带权并查集去做。具体的说,我们对并查集的每条儿子到父亲的边带上权。 1 1 代表儿子与父亲是不同颜色的, 0 0 则代表相同。每次连接两个并查集的时候,可以通过简单的操作实现连边。

  • 总之,用带权并查集处理后可以很轻松的判断是否有奇环。

  • 之后我们把那些并不完全覆盖 [ L , R ] [L,R] 的边继续往下分治,就像线段树一样。那么显然只会分 L o g Log 次,而每次我们都会在并查集里加边,时间复杂度也是一个 L o g Log 的,所以总的时间复杂度就是两个 L o g Log 的。

  • 注意并查集要用按秩合并。路径压缩因为会改变树的形态,对我们每次清除标记有影响。因为是在每次往左往右递归完之后,才把对当前区间影响的那些记录给消除掉,所以这个可以随便维护个数组或vector之类的。每次递归往下带的时候可以直接套一个vector,常数很大,实际上可以更快。

猜你喜欢

转载自blog.csdn.net/Algor_pro_king_John/article/details/88649987