CodeForces 505B(并查集)

    xiaoxiao2025-02-15  17

    Mr. Kitayuta's Colorful Graph Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit   Practice  CodeForces 505B

    Description

    Mr. Kitayuta has just bought an undirected graph consisting of n vertices and m edges. The vertices of the graph are numbered from 1 ton. 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 ≤ 100, 1 ≤ m ≤ 100), 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, if i ≠ j(ai, bi, ci) ≠ (aj, bj, cj).

    The next line contains a integer — q (1 ≤ q ≤ 100), 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 Input

    Input 4 5 1 2 1 1 2 2 2 3 1 2 3 3 2 4 3 3 1 2 3 4 1 4 Output 2 1 0 Input 5 7 1 5 1 2 5 1 3 5 1 4 5 1 1 2 2 2 3 2 3 4 2 5 1 5 5 1 2 5 1 5 1 4 Output 1 1 1 1 2

    Hint

    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.

    题意:

    给一个n个点,m条边的无向图,每条边有一个颜色color,1<=color<=m,问任意两点之间仅用一种颜色就能连通的道路有几条。

    思路:

    对边集数组按颜色不降序排序,以颜色种类维护并查集。对每个查询进行并查集的Find操作求和即可。

    代码:

    #include <iostream> #include <cstring> #include <algorithm> #include <vector> #include <cstdio> using namespace std; struct Edge { int from, to, w; bool operator<(const Edge &a)const{ return w<a.w; } }; struct node { int first, second; }; int n, m; int pre[10010]; Edge edges[110]; node check[110]; void init(){ for(int i=0; i<10010; i++) pre[i] = i; for(int i=0; i<110; i++){ check[i].first = -2; check[i].second = -1; } } int Find(int x){ if(x==pre[x]) return x; else return Find(pre[x]); } bool unite(int x, int y){ x = Find(x); y = Find(y); if(x==y) return false; pre[x] = y; return true; } void sol(int s, int e, int flag){ if(s==-2&&e==-1) return; for(int i=s; i<=e; i++){ bool waste = unite(edges[i].from+flag*n, edges[i].to+flag*n); } return; } int main(){ int cnt, a, b; while(scanf("%d%d", &n, &m)!=EOF){ for(int i=0; i<m; i++){ scanf("%d%d%d", &edges[i].from, &edges[i].to, &edges[i].w); } sort(edges, edges+m); init(); for(int i=0; i<m; i++){ int tmp = check[edges[i].w].first; check[edges[i].w].first = (tmp==-2)?i:tmp; check[edges[i].w].second = i; } for(int i=1; i<=m; i++){ sol(check[i].first, check[i].second, i-1); } scanf("%d", &cnt); for(int i=0; i<cnt; i++){ scanf("%d%d", &a, &b); int ans = 0; for(int j=0; j<m; j++){ int x = Find(a+j*n); int y = Find(b+j*n); if(x==y){ ans++; } } printf("%d\n", ans); } } return 0; }

    转载请注明原文地址: https://ju.6miu.com/read-1296462.html
    最新回复(0)