点击hdu 1856思路:
思路: 离散化+并查集
分析:
1 点数最多为10^7,但是边数最多10^5,所以我们必须采用离散化,然后利用带权并查集的思想,rank[x]表示的是以x为根节点的集合的元素个数
2 这一题主要注意的就是当n = 0的时候,因为题目说了刚开始有10^7个人在房间里面,所以n = 0的时候最多有一个人出去
代码:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int MAXN = 200010; struct Node{ int x; int y; }; Node node[MAXN]; int n , pos; int num[MAXN]; int father[MAXN]; int rank[MAXN]; void init(){ sort(num , num+pos); pos = unique(num , num+pos)-num; for(int i = 0 ; i <= pos ; i++){ father[i] = i; rank[i] = 1; } } int search(int x){ int left = 0; int right = pos-1; while(left <= right){ int mid = (left+right)>>1; if(num[mid] == x) return mid+1; else if(num[mid] < x) left = mid+1; else right = mid-1; } } int find(int x){ if(father[x] != x) father[x] = find(father[x]); return father[x]; } int solve(){ init(); int ans = 0; for(int i = 0 ; i < n ; i++){ int x = search(node[i].x); int y = search(node[i].y); int fx = find(x); int fy = find(y); if(fx != fy){ father[fx] = fy; rank[fy] += rank[fx]; ans = max(ans , rank[fy]); } } return n == 0 ? 1 : ans; } int main(){ while(scanf("%d" , &n) != EOF){ pos = 0; for(int i = 0 ; i < n ; i++){ scanf("%d%d" , &node[i].x , &node[i].y); num[pos++] = node[i].x; num[pos++] = node[i].y; } printf("%d\n" , solve()); } return 0; }