Mr. Kitayuta's Colorful Graph

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/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+5, maxm = 1e5+5;

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() > 1){
        blc.push_back(tmp[x]);
        tmp[x].clear();
    }
    if(vis[x]){
        vis[x] = false;
        rak[x] = pa[x] = 0;
    }
}

const uint32_t MAXB = 448;

int ans[MAXB+5][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(2*m/sqrt(2*m));
    int i,j;
    for(i = 1; i <= m; i++){
        scanf("%d%d%d",a+i,b+i,&j);
        add_e(j,i);
    }

    for(i = 1; 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 = 0; i < (int)blc.size(); i++){
        for(auto v: blc[i]){
            in_blk[v].push_back(i);
        }
    }

    int id_cnt = 0;
    for(i = 1; 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 = 0;
            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 0;
}

Mr. Kitayuta's Colorful Graph

时间: 2024-10-12 21:27:10

Mr. Kitayuta's Colorful Graph的相关文章

CodeForces 505B Mr. Kitayuta&#39;s Colorful Graph

Mr. Kitayuta's Colorful Graph Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Practice CodeForces 505B Description Mr. Kitayuta has just bought an undirected graph consisting of n vertices and m edges. The

codeforces 505B Mr. Kitayuta&#39;s Colorful Graph(水题)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Mr. Kitayuta's Colorful Graph Mr. Kitayuta has just bought an undirected graph consisting of n vertices and m edges. The vertices of the graph are numbered from 1 to n. Each edge, namely edge

Codeforces Round #286 div.1 D 506D D. Mr. Kitayuta&#39;s Colorful Graph【并查集】

题目链接:http://codeforces.com/problemset/problem/506/D 题目大意: 给出n个顶点,m条边,每条边上有一个数字,代表某个颜色.不同数字代表不同的颜色.有很多个询问,每个询问问有多少条纯种颜色的路径使得某两个点联通. 分析: 这个题一看就想用并查集来搞,每种颜色用一个并查集处理.对于输入的每条边,我们只需要将这两个点在这条边的颜色对应的并查集中合并就好了.查询的时候,我们只需要检测这两个点在多少个颜色对应的并查集中是在统一集合中的,那么就有多少条纯种颜

B. Mr. Kitayuta&#39;s Colorful Graph (CF #286 (Div. 2) 并查集)

B. Mr. Kitayuta's Colorful Graph time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Mr. Kitayuta has just bought an undirected graph consisting of n vertices and m edges. The vertices of the g

Codeforces 506D Mr. Kitayuta&#39;s Colorful Graph 并查集+水水的分类讨论+水水的离线预处理

首先读入所有的边与询问.将边按颜色分类. 按颜色进行并查集, 若此并查集内的点<= 100,则100*100/2的枚举是否联通. 若此并查集内的点  > 100,则将与这些点相关的所有询问查一遍. 那么时间复杂度为100*100/2*(M/100),或者为M/100*Q. 极限的时候两种方法都在一亿左右了,而且每次还需要在map里搞一搞,还要查询是否联通,不知道为啥没有超时.. #include <algorithm> #include <iostream> #incl

CF 505B Mr. Kitayuta&#39;s Colorful Graph(最短路)

题意  求两点之间有多少不同颜色的路径 范围比较小  可以直接floyd #include<cstdio> #include<cstring> using namespace std; const int N = 105; int d[N][N][N], ans; int main() { int a, b, c, n, m, q; while(~scanf("%d%d", &n, &m)) { memset(d, 0, sizeof(d));

Codeforces Round #286 (Div. 2)B. Mr. Kitayuta&#39;s Colorful Graph(dfs,暴力)

数据规模小,所以就暴力枚举每一种颜色的边就行了. #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<cmath> #include<map> #include<set> #include<vector> #include<algorithm>

Codeforces Round #286 (Div. 2) B. Mr. Kitayuta&#39;s Colorful Graph +foyd算法的应用

B. Mr. Kitayuta's Colorful Graph time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Mr. Kitayuta has just bought an undirected graph consisting of n vertices and m edges. The vertices of the g

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

题目传送门 1 /* 2 题意:两点之间有不同颜色的线连通,问两点间单一颜色连通的路径有几条 3 DFS:暴力每个颜色,以u走到v为结束标志,累加条数 4 注意:无向图 5 */ 6 #include <cstdio> 7 #include <iostream> 8 #include <algorithm> 9 #include <cstring> 10 #include <string> 11 #include <vector> 1