brute force ? 其实是平方分解。很容易想到的是每一个颜色建一个图,然后并查集维护一下连通性。

问题在于颜色有O(m)种,每种颜色的图点数都是O(n)的,因此并查集的空间只能重复利用。

但是可以把以O(m)的空间把有用的连通块信息保留下来。

之后的处理可以借鉴分块的思想。

记点v属于的连通块数量为b(v),对于询问x,y ,根据点所在的连通块信息,可以以O(max(b(x),b(y)))的时间回答出来。

设置一个阀值B,对于b(v)>B,提前预处理,小于B的就暴力回答。

因为一条边最多增加两个b(v)值,所有b(v)的和是O(m)的。 最多有m/B个v满足b(v)大于B,对于每个这样的v,O(m)历遍,O(m)的空间记录答案。

两部分的复杂度是O(m/B*m + B*q),类似分块的取法,取B = m/sqrt(q),复杂度为O(m*sqrt(q))。

/*********************************************************
* --------------Alfheim-------------- *
* author AbyssalFish *
**********************************************************/
#include<bits/stdc++.h>
using namespace std; typedef long long ll; const int maxn = 1e5+, maxm = 1e5+; int pa[maxn], rak[maxn]; int fd(int x)
{
return pa[x]? pa[x] = fd(pa[x]): x;
} inline void joint(int a,int b)
{
int x = fd(a), y = fd(b);
if(x != y){
if(rak[x] < rak[y]){
pa[x] = y;
}
else {
pa[y] = x;
if(rak[x] == rak[y]) rak[x]++;
}
}
} int a[maxm],b[maxm];
bool vis[maxn]; int hd_c[maxn], nx_e[maxm]; inline void add_e(int cl,int i)
{
nx_e[i] = hd_c[cl];
hd_c[cl] = i;
} typedef vector<int> Block;
typedef vector<int> v_int; vector<Block> blc;
Block tmp[maxn];
v_int in_blk[maxn]; inline void add_blc(int x)
{
if(!vis[x]){
vis[x] = true;
tmp[fd(x)].push_back(x);
}
} inline void dump(int x)
{
if(tmp[x].size() > ){
blc.push_back(tmp[x]);
tmp[x].clear();
}
if(vis[x]){
vis[x] = false;
rak[x] = pa[x] = ;
}
} const uint32_t MAXB = ; int ans[MAXB+][maxn];
int id[maxn]; //#define LOCAL
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
#endif
//cout<<(2*maxm/sqrt(2*maxm));
int n,m,q;
scanf("%d%d",&n,&m);
uint32_t B = floor(*m/sqrt(*m));
int i,j;
for(i = ; i <= m; i++){
scanf("%d%d%d",a+i,b+i,&j);
add_e(j,i);
} for(i = ; i <= m; i++){
for(j = hd_c[i]; j; j = nx_e[j]){
joint(a[j],b[j]);
}
for(j = hd_c[i]; j; j = nx_e[j]){
add_blc(a[j]);
add_blc(b[j]);
}
for(j = hd_c[i]; j; j = nx_e[j]){
dump(a[j]);
dump(b[j]);
}
} for(i = ; i < (int)blc.size(); i++){
for(auto v: blc[i]){
in_blk[v].push_back(i);
}
} int id_cnt = ;
for(i = ; i <= n; i++){
if(in_blk[i].size() > B){
id[i] = ++id_cnt;
for(auto b_id: in_blk[i]){
for(auto v: blc[b_id]){
ans[id_cnt][v]++;
}
}
}
} scanf("%d",&q);
while(q--){
int x,y; scanf("%d%d",&x,&y);
int res;
if(id[x]) res = ans[id[x]][y];
else if(id[y]) res = ans[id[y]][x];
else {
res = i = j = ;
v_int &X = in_blk[x], &Y = in_blk[y];
n = X.size(); m = Y.size();
while(i < n && j < m){
if(X[i] == Y[j]){
res++; i++; j++;
}
else {
X[i] < Y[j] ? i++ : j++;
}
}
}
printf("%d\n",res);
} return ;
}

CodeForces 506D Mr. Kitayuta's Colorful Graph的更多相关文章

  1. Codeforces 506D Mr. Kitayuta's Colorful Graph(分块 + 并查集)

    题目链接  Mr. Kitayuta's Colorful Graph 把每种颜色分开来考虑. 所有的颜色分为两种:涉及的点的个数 $> \sqrt{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. python模块之numpy

    Numpy是一个第三方库,是数组相关的运算 通过pip安装:pip install numpy Anaconda python的一个科学计算发行版本,安装后将不必单独安装numpy,下面的库模块也将不 ...

  2. 记录CentOS7.X版本下安装MySQL5.7数据库

    记录CentOS7.X版本下安装MySQL5.7数据库  设置rpm下载目录在/opt目录下新建一个目录存放mysql cd /opt sudo mkdir mysql12  下载MySQL的源 wg ...

  3. java后台获取服务器相对路径,获取当前时间yyyyMMddHHmmssSSS

    SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmssSSS"); Date date = new Date( ...

  4. 019-MD5加密模板工具类

    1 MD5加密工具类 package ${enclosing_package}; import java.math.BigInteger; import java.security.MessageDi ...

  5. git跟svn 服务端对比

    Git已经火了很久,简单的使用也没有问题,但有几个问题一直以来都没有搞清楚:git跟svn有哪些异同,两者相互的优劣是什么,git的分布式怎么理解,为什么有离线提交,,,自己动手,分别看一下服务端跟客 ...

  6. 关于花瓣网header条的思考

    最近忙着俱乐部招新的事情,每一次培训都会给学员布置作业,但是作业积累在手上并没有长久的保存价值,于是萌生了一个创建俱乐部网站平台的想法.为了充当好PM这个角色,学习了Axure软件的用法,并且首次制作 ...

  7. rsync 命令中的路径斜线

    rsync命令大家都知道,但是其中的一个小细节比较容易被忽略,那就是 路径结尾的 "/" ,在路径的结尾有没有斜线,结果是大不同的.现举例说明: 假设现有两个目录,一个名为sour ...

  8. php锁定文本框内容的方法

    有时候我们希望表单中的文本框是只读的,让用户不能修改其中的信息,如<input type="text" name="zg" value="中国& ...

  9. php高级教程

    PHP - 多维数组 多维数组指的是包含一个或多个数组的数组. 注释:数组的维度指示您需要选择元素的索引数. 对于二维数组,您需要两个索引来选取元素 对于三维数组,您需要三个索引来选取元素 PHP - ...

  10. 用Java 8 Lambda表达式实现设计模式:命令模式

    在这篇博客里,我将说明如何在使用 Java 8 Lambda表达式 的函数式编程方式 时实现 命令 设计模式 .命令模式的目标是将请求封装成一个对象,从对客户端的不同类型请求,例如队列或日志请求参数化 ...