CodeForces 505B(并查集)

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

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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值