码迷,mamicode.com
首页 > 其他好文 > 详细

fzu2192,种类并查集

时间:2015-05-08 20:21:17      阅读:117      评论:0      收藏:0      [点我收藏+]

标签:

题意是中文的,就不说了;

这里用到种类并查集,分别用1-N;N-2N,2N-3N代表城市,服务,人;

然后要注意这几点:

1:不要用rank数组了,因为连边要自己控制。

2:在unite函数的时候,比较一下x和y,控制把大的连到小的上面,这样之后寻味的时候,find()一定会找到最小的(城市),然后如果大于N,就说明他没有连到城市,输出0;


代码如下:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<stdlib.h>

using namespace std;
const int N = 300000;
int par[999999], last[999999];

void init(int n)
{
	int i, j;
	for (int i = 0; i<n; i++)
	{
		par[i] = i;
	}
}

int find(int x)
{
	if (par[x] != x) par[x] = find(par[x]);
	return par[x];
}
void unite(int x, int y)
{
	x = find(x);
	y = find(y);
	if (x == y) return;
	int mmax = max(x, y);
	int mmin = min(x, y);
	par[mmax] =mmin;
	
}

bool same(int x, int y)
{
	return find(x) == find(y);
}
int main()
{
	int n, m, q, i, j, k, good, city, people, kind, query;
	while (~scanf("%d%d%d", &n, &m, &q))
	{
		init(999999);

		for (i = 0; i<n; i++)
		{
			scanf("%d%d", &good, &city);
			if (city)
			{
				unite(good + N, city);
			}
		}

		for (i = 0; i<m; i++)
		{
			scanf("%d%d%d", &people, &good, &city);
			if (city)
			{
				unite(people + 2 * N,good+N);
				unite(good + N, city);
			}
			else
			{
				
				unite(people + 2 * N, good + N);
				
			}
			
		}

	

		for (i = 0; i<q; i++)
		{
			int temp;
			scanf("%d%d", &kind, &query);
			if (kind == 0)
			{
				 temp = find(query + N);
	
			}
			if (kind == 1)
			{
				 temp = find(query + 2*N);
			}

			if (temp>N)
			{
				printf("0\n");
				continue;
			}
			printf("%d\n", temp);

		}

	}




	return 0;
}


fzu2192,种类并查集

标签:

原文地址:http://blog.csdn.net/nie8484/article/details/45584469

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!