Codeforces 505B - Mr. Kitayuta's Colorful Graph DFS或并查集

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



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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值