题目链接  Mr. Kitayuta's Colorful Graph

把每种颜色分开来考虑。

所有的颜色分为两种:涉及的点的个数 $> \sqrt{n}$    涉及的点的个数 $<= \sqrt{n}$

对于第一种颜色,并查集缩点之后对每个询问依次处理过来若两点连通则答案加一。

对于第二种颜色,并查集缩点之后对该颜色涉及的所有点两两之间判断是否连通,

若连通则另外开一个$map$记录答案。

最后把两个部分的答案加起来即可。

细节问题  由于每种颜色处理完之后并查集都要重新初始化,对于第一种颜色的做法,只要$memset$即可。

第二种颜色总数可能较多,所以把之前并查集的操作撤销即可。

#include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b)	for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i)
#define MP make_pair
#define fi first
#define se second typedef pair <int, int> PII; const int N = 1e5 + 10; struct node{ int x, y, ans; } q[N]; unordered_map <int, int> mp[N];
map <PII, int> id, ret;
vector <int> v[N];
vector <node> e[N];
stack <PII> s;
int n, m, qu, cnt, line;
int father[N], c[N]; int getfather(int x){ return father[x] ? father[x] = getfather(father[x]) : x; } int gf(int x){
if (father[x]){
s.push(MP(x, father[x]));
father[x] = getfather(father[x]);
return father[x];
} else return x;
} int main(){ scanf("%d%d", &n, &m);
rep(i, 1, m){
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
if (x > y) swap(x, y);
mp[z][x] = mp[z][y] = 1;
e[z].push_back({x, y});
} scanf("%d", &qu);
rep(i, 1, qu){
scanf("%d%d", &q[i].x, &q[i].y);
if (q[i].x > q[i].y) swap(q[i].x, q[i].y);
id[MP(q[i].x, q[i].y)] = i;
} rep(i, 1, m){
int now = (int)mp[i].size();
if (now > 0) v[now].push_back(i);
} line = sqrt(n);
rep(i, 1, line){
for (auto col : v[i]){
while (!s.empty()) s.pop();
for (auto edge : e[col]){
int x = edge.x, y = edge.y;
int fx = gf(x), fy = gf(y);
if (fx != fy){
s.push(MP(fx, father[fx]));
father[fx] = fy;
}
} cnt = 0;
for (auto u : mp[col]) c[++cnt] = u.fi;
rep(j, 1, cnt - 1){
rep(k, j + 1, cnt){
int x = c[j], y = c[k];
if (x > y) swap(x, y);
if (gf(x) == gf(y)) ++ret[MP(x, y)];
}
} while (!s.empty()){
father[s.top().fi] = s.top().se;
s.pop();
} }
} rep(i, line + 1, n){
for (auto col : v[i]){
memset(father, 0, sizeof father);
for (auto edge : e[col]){
int x = edge.x, y = edge.y;
int fx = getfather(x), fy = getfather(y);
if (fx != fy) father[fx] = fy;
} rep(j, 1, qu) if (getfather(q[j].x) == getfather(q[j].y)) ++q[j].ans;
}
} rep(i, 1, qu) printf("%d\n", q[i].ans + ret[MP(q[i].x, q[i].y)]);
return 0;
}

  

Codeforces 506D Mr. Kitayuta's Colorful Graph(分块 + 并查集)的更多相关文章

  1. CodeForces 506D Mr. Kitayuta's Colorful Graph

    brute force ? 其实是平方分解.很容易想到的是每一个颜色建一个图,然后并查集维护一下连通性. 问题在于颜色有O(m)种,每种颜色的图点数都是O(n)的,因此并查集的空间只能重复利用. 但是 ...

  2. CodeForces 505B Mr. Kitayuta's Colorful Graph

    Mr. Kitayuta's Colorful Graph Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d ...

  3. codeforces 505B Mr. Kitayuta's Colorful Graph(水题)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Mr. Kitayuta's Colorful Graph Mr. Kitayut ...

  4. CodeForces - 505B Mr. Kitayuta's Colorful Graph 二维并查集

    Mr. Kitayuta's Colorful Graph Mr. Kitayuta has just bought an undirected graph consisting of n verti ...

  5. Codeforces Round #286 (Div. 1) D. Mr. Kitayuta's Colorful Graph 并查集

    D. Mr. Kitayuta's Colorful Graph Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/ ...

  6. DFS/并查集 Codeforces Round #286 (Div. 2) B - Mr. Kitayuta's Colorful Graph

    题目传送门 /* 题意:两点之间有不同颜色的线连通,问两点间单一颜色连通的路径有几条 DFS:暴力每个颜色,以u走到v为结束标志,累加条数 注意:无向图 */ #include <cstdio& ...

  7. Codeforces Round #286 (Div. 2) B. Mr. Kitayuta's Colorful Graph dfs

    B. Mr. Kitayuta's Colorful Graph time limit per test 1 second memory limit per test 256 megabytes in ...

  8. Codeforces Round #286 (Div. 1) D. Mr. Kitayuta's Colorful Graph

    D - Mr. Kitayuta's Colorful Graph 思路:我是暴力搞过去没有将答案离线,感觉将答案的离线的方法很巧妙.. 对于一个不大于sqrt(n) 的块,我们n^2暴力枚举, 对于 ...

  9. B. Mr. Kitayuta's Colorful Graph

     B. Mr. Kitayuta's Colorful Graph  time limit per test 1 second Mr. Kitayuta has just bought an undi ...

随机推荐

  1. 《Scrum实战》第4次课【全职的Scrum Master】作业汇总

    1组: 孟帅 http://www.cnblogs.com/mengshuai1982/p/7375008.html 3组: 张亚辉 http://www.jianshu.com/p/df9eee08 ...

  2. leetcode 【 Triangle 】python 实现

    题目: Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjace ...

  3. _cdecl _stdcall

    __cdecl程序的压栈方式为C风格__stdcall为PASCAL风格 举个例子:(1)   C函数  Fun1(a,b,c)   函数调用时,参数压栈顺序为 c , b , a(2)   PASC ...

  4. Python-S9-Day99——Web前端框架之Vue.js

    01课程安排 02let和const: 03 箭头函数 04 对象的单体模式 05 Node.js介绍和npm操作 06 Webpack,babel介绍和Vue的第一个案例 01课程安排 1.1 ht ...

  5. python深浅拷贝以及数据在内存中储存方法

    要搞懂深浅拷贝,首先要明白数据在内存里的储存方法. 一个变量的储存,首先是变量名加上储存内容的ID,通过ID去找到变量名所对应的内容, 当我们对数据进行赋值时,其实是把内容的整体地址赋给别的变量名(相 ...

  6. Java学习5之接口

    接口不是类,而是一个特殊的名称,使用interface关键字.子类可以实现多个接口. 接口实现: public class Child extends Parent implements Interf ...

  7. LeetCode——Problem3:Longest Substring Without Repeating Characters

    哎哟我天啊.这道题快折磨死我了.刚开始连题都没看明白,就是不知道substring是什么意思.研究了好长时间才看出来的. 光辉历史呀...菜死了 1.题目 Given a string, find t ...

  8. Html语言的标签讲解

    一.head头部中的内容: 1.<meta charset="UTF-8"> <--!告诉浏览器什么编码--> 2.<meta http-equiv= ...

  9. Vue在tradingView遇到的问题

    K线图刷新或重新加载时闪白 首先需要了解的是,闪白是 iframe的机制 所以只要解决掉iframe就可以了 首先找到 charting_library.min.js 搜索 找到配置项 style=& ...

  10. Codeforces Round #418 (Div. 2) A+B+C!

    终判才知道自己失了智.本场据说是chinese专场,可是请允许我吐槽一下题意! A. An abandoned sentiment from past shabi贪心手残for循环边界写错了竟然还过了 ...