标签:
题意是中文的,就不说了;
这里用到种类并查集,分别用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;
}标签:
原文地址:http://blog.csdn.net/nie8484/article/details/45584469