题目链接  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. [USACO]奶牛抗议(DP+树状数组+离散化)

    Description 约翰家的N头奶牛聚集在一起,排成一列,正在进行一项抗议活动.第i头奶牛的理智度 为Ai,Ai可能是负数.约翰希望奶牛在抗议时保持理性,为此,他打算将所有的奶牛隔离成 若干个小组 ...

  2. Contest - 中南大学第六届大学生程序设计竞赛(Semilive)

    题1:1160十进制-十六进制 注意他给的数据范围 2^31,int是 2^31-1 #include<iostream> using namespace std; int main() ...

  3. 自己用C语言写RH850 F1KM serial bootloader

    了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). 手上有块Renesas ...

  4. TCP/IP网络编程之多进程服务端(一)

    进程概念及应用 我们知道,监听套接字会有一个等待队列,里面存放着不同客户端的连接请求,如果有一百个客户端,每个客户端的请求处理是0.5s,第一个客户端当然不会不满,但第一百个客户端就会有相当大的意见了 ...

  5. easyui-numberbox限定仅输入数字

    许多必填项都涉及到数字,比如电话号码,身份证号这些要求用户在输入时只能输入数字.Easyui提供了数字框控件,允许用户只输入数字, <td> <input id="ssd& ...

  6. leetcode 【 Swap Nodes in Pairs 】python 实现

    题目: Given a linked list, swap every two adjacent nodes and return its head. For example,Given 1-> ...

  7. 【Remove Elements】cpp

    题目: Given an array and a value, remove all instances of that value in place and return the new lengt ...

  8. 【Remove Duplicates from Sorted Array II】cpp

    题目: Follow up for "Remove Duplicates":What if duplicates are allowed at most twice? For ex ...

  9. RHCE认证经典考题

    1:按要求创建用户组及多个用户,设置用户的候选组,设置用户的默认shell. 创建组adminuser. 创建用户natasha和harry属于该组(该组为他们的第二个组). 创建用户sarah,不属 ...

  10. Wordpress 数据库查询错误 Call to a member function get_results() on null

    在插件中的一个文件使用如下代码,无法查询 <body> <?php global $wpdb; $sql = ""; $sql = "SELECT * ...