Codeforces 505B - Mr. Kitayuta's Colorful Graph
一个无向图包含n个点m条边,顶点编号从1到n。 对于每条边有颜色ci, 连接着顶点 ai 和 b i.
下面有q个询问.每条询问有两个整数 — ui 和 vi.
找到满足下面条件的颜色个数: 同一种颜色的路径连接顶点 ui 和 顶点 vi
Input
第一行是两个整数 — n and m (2 ≤ n ≤ 100, 1 ≤ m ≤ 100), 代表着定点个数和边的个数
接下来m行有三个整数 — ai, bi (1 ≤ ai < bi ≤ n) and ci (1 ≤ ci ≤ m).
下一行有一个整数 — q (1 ≤ q ≤ 100), 代表询问次数
接下来q行,每行两个整数 — ui 和 vi (1 ≤ ui, vi ≤ n). 默认 ui ≠ vi.
Output
对于每次询问,在单独的一行输出答案
Example
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
题意换成中文的了,很容易理解
思路:这题的数据量很小,直接深搜就行
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int e[101][101][101];
bool vis[100];
int ans;
int m[101][101];
int MAX1;
int n,w;
void dfs(int num,int a,int b,int q)
{
vis[q]=true;
if(q==b)
{
ans=1;
return;
}
for(int i=1;i<=n;i++)
if(e[num][q][i]&&!vis[i])
{
dfs(num,a,b,i);
}
}
int main(void)
{
scanf("%d%d",&n,&w);
for(int i=1;i<=w;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
e[c][a][b]=1;
e[c][b][a]=1;
}
int q;
scanf("%d",&q);
for(int i=1;i<=q;i++)
{
int a,b;
int count=0;
scanf("%d%d",&a,&b);
if(m[a][b]){//用一个m数组主要为了处理重复数据的出现
printf("%d\n",m[a][b]);
continue;
}
for(int i=1;i<=w;i++)
{
memset(vis,0,sizeof(vis));
ans=0;
dfs(i,a,b,a);
if(ans) count++;
}
m[a][b]=m[b][a]=count;
printf("%d\n",count);
}
}
另一种实现方法就是二维并查集,第一次写二维的并查集
#include<stdio.h>
int pre[101][101];
int n,m;
void init()
{
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
pre[i][j]=j;
}
int find(int color,int x)
{
if(pre[color][x]==x)
return x;
else{
pre[color][x]=find(color,pre[color][x]);
return pre[color][x];
}
}
void join(int color,int a,int b)
{
int x=find(color,a);
int y=find(color,b);
if(x!=y)
pre[color][y]=x;
}
int main(void)
{
scanf("%d%d",&n,&m);
init();
int a,b,c;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&c);
join(c,a,b);
}
int p;
scanf("%d",&p);
for(int i=1;i<=p;i++)
{
scanf("%d%d",&a,&b);
int ans=0;
for(int j=1;j<=m;j++)
{
int tx=find(j,a);
int ty=find(j,b);
if(tx==ty) ans++;
}
printf("%d\n",ans);
}
return 0;
}