Codeforces 506D:Mr. Kitayuta's Colorful Graph 并查集

来源:互联网 发布:知天下 两性 编辑:程序博客网 时间:2024/06/05 20:12

D. Mr. Kitayuta's Colorful Graph
time limit per test
4 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Mr. Kitayuta has just bought an undirected graph with n vertices and m edges. The vertices of the graph are numbered from 1 to n. Each edge, namely edge i, has a color ci, connecting vertex ai and bi.

Mr. Kitayuta wants you to process the following q queries.

In the i-th query, he gives you two integers - ui and vi.

Find the number of the colors that satisfy the following condition: the edges of that color connect vertex ui and vertex vi directly or indirectly.

Input

The first line of the input contains space-separated two integers - n and m(2 ≤ n ≤ 105, 1 ≤ m ≤ 105), denoting the number of the vertices and the number of the edges, respectively.

The next m lines contain space-separated three integers - aibi(1 ≤ ai < bi ≤ n) and ci(1 ≤ ci ≤ m). Note that there can be multiple edges between two vertices. However, there are no multiple edges of the same color between two vertices, that is, ifi ≠ j, (ai, bi, ci) ≠ (aj, bj, cj).

The next line contains a integer- q(1 ≤ q ≤ 105), denoting the number of the queries.

Then follows q lines, containing space-separated two integers - ui and vi(1 ≤ ui, vi ≤ n). It is guaranteed that ui ≠ vi.

Output

For each query, print the answer in a separate line.

Sample test(s)
input
4 51 2 11 2 22 3 12 3 32 4 331 23 41 4
output
210
input
5 71 5 12 5 13 5 14 5 11 2 22 3 23 4 251 55 12 51 51 4
output
11112
Note

Let's consider the first sample.

The figure above shows the first sample.
  • Vertex 1 and vertex 2 are connected by color 1 and 2.
  • Vertex 3 and vertex 4 are connected by color 3.
  • Vertex 1 and vertex 4 are not connected by any single color.

题意是给出了通过不同颜色的边连接的一些点,有Q个查询,查询两个点可以用多少种不同颜色的边连接起来。

如果是一个颜色的边,然后Q个询问,询问两个点是否被连接,可以离线并查集搞。现在是m个颜色的边,那就一个一个颜色并查集搞。

但是,这里还是有问题,就是如何输出结果,这里也学习到了新姿势。就是如果这个颜色的点很多的话,那就遍历Q个查询,记录结果。如果这个颜色的点很少的话,那就O(n^2)记录这些颜色的点。

代码:

#pragma warning(disable:4996)  #include <iostream>#include <algorithm>#include <cstring>#include <vector>#include <string>#include <cstdio>#include <cmath>#include <queue>#include <stack>#include <set>#include <map>using namespace std;#define INF 0x3ffffffftypedef long long ll;const int mod = 1e9 + 7;const int maxn = 1e5 + 5;int n, m, q;vector<int>po;vector<pair<int, int>>edg[maxn];map<pair<int, int>, int>res;int fa[maxn], ans[maxn], qu[maxn], qv[maxn], cor[maxn];int find(int x){return x == fa[x] ? x : fa[x] = find(fa[x]);}void merge(int x, int y){fa[x] = y;}void input(){int i, s, e, cor;scanf("%d%d", &n, &m);for (i = 1; i <= m; i++){scanf("%d%d%d", &s, &e, &cor);edg[cor].push_back(make_pair(s, e));}scanf("%d", &q);for (i = 1; i <= q; i++){scanf("%d%d", &qu[i], &qv[i]);}}void solve(){int i, j, k;for (i = 1; i <= m; i++){int sz = edg[i].size();if (sz == 0)continue;po.clear();for (j = 0; j<sz; j++){po.push_back(edg[i][j].first);po.push_back(edg[i][j].second);}sort(po.begin(), po.end());po.erase(unique(po.begin(), po.end()), po.end());int po_sz = po.size();for (j = 0; j<po_sz; j++){int poin = po[j];cor[poin] = i;fa[poin] = poin;}for (j = 0; j<sz; j++){int u = edg[i][j].first;int v = edg[i][j].second;if (find(u) != find(v)){merge(find(u), find(v));}}if ((ll)po_sz*(ll)po_sz > n){for (j = 1; j <= q; j++){if (cor[qu[j]] == i&&cor[qv[j]] == i){if (find(qu[j]) == find(qv[j])){ans[j]++;}}}}else{for (j = 0; j < po_sz; j++){for (k = j + 1; k < po_sz; k++){if (find(po[j]) == find(po[k])){res[make_pair(po[k], po[j])]++;res[make_pair(po[j], po[k])]++;}}}}}for (i = 1; i <= q; i++){printf("%d\n", ans[i] + res[make_pair(qu[i], qv[i])]);}}int main(){//freopen("i.txt","r",stdin);//freopen("o.txt","w",stdout);input();solve();//system("pause");return 0;}

0 0