codeforces 505B Mr. Kitayuta's Colorful Graph

来源:互联网 发布:平安交易软件下载 编辑:程序博客网 时间:2024/06/01 19:16

B.Mr.KitayutasColorfulGraph

time limit per test1 second
memory limit per test256 megabytes

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 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 ≤ 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 — ai, bi (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.

Examples
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,接下来m行为两个城市的路的颜色。然后q个询问,问你从a到b有几条路可以走,就是只用一种颜色的路能够间接或者直接的走。

我的思路:
用一个三维数组来存储从a城市到b城市的路。w[a][b][c]表示可以通过路c从a走到b。
题目类型:并查集。
k,i,j那里是一个并查集,本来不知道并查集是什么(其实现在也不知道),周赛时一直以为是3个并列的for循环,wa了无数发也没发现错误,真是要吐血。

     for(l=1;l<=m;l++)     //先是列举所有的路       for(k=1;k<=n;k++)           for(i=1;i<=n;i++)          for(j=1;j<=n;j++)    {        if(w[i][k][l]==1&&w[k][j][l]==1)            {                w[i][j][l]=1;                w[j][i][l]=1;            }    }

这部分应该很好理解,就是a到b能通过w连通,b到c能通过w连通,那么很明显a和c也能通过w连通。
这样所以从i到j能连通的数量都求出来了,查询就是枚举边,边连通就+1结果很容易就出来了。

#include<stdio.h>#include<iostream>#include<string.h>#define N 105#define M 105using namespace std;int w[N][N][M];int main(){    int n,m,i,j,k,l,a,b,c;    scanf("%d%d",&n,&m);    memset(w,0,sizeof(w));    //初始化为0,表示无路可走    for(i=1;i<=n;i++)                 for(j=1;j<=m;j++)        w[i][i][j]=1;         //自己到自己肯定是连通的,这里可能不初始化也不重要    for(i=1;i<=m;i++)    {        scanf("%d%d%d",&a,&b,&c);        w[a][b][c]=1;        w[b][a][c]=1;       //w为1表示有路连通了    }      for(l=1;l<=m;l++)     //先是列举所有的路        for(k=1;k<=n;k++)           for(i=1;i<=n;i++)          for(j=1;j<=n;j++)    {        if(w[i][k][l]==1&&w[k][j][l]==1)            {                w[i][j][l]=1;                w[j][i][l]=1;            }    }    int q,x,y;    scanf("%d",&q);    while(q--)    {        int ans=0;        scanf("%d%d",&x,&y);        for(l=1;l<=m;l++)            if(w[x][y][l]==1)            ans++;        printf("%d\n",ans);    }    return 0;}

这张图表示我当时被zhzq提醒是并查集出错的心情:
这里写图片描述

2 0
原创粉丝点击