标签:
题意是中文的,就不说了;
这里用到种类并查集,分别用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