http://acm.hdu.edu.cn/showproblem.php?pid=1856
这道题目的目的是想知道经过一系列的合并操作之后,查询在所有的子树中,秩的最大值是多少,简而言之,就是最大的那颗子树包含了多少个节点。
很显然,这个问题也能够同时使用两种优化策略,只不过因为要求最大秩的值,需要有一个变量来记录。那么在哪个地方来更新它是最好的呢?我们知道,在按秩进行合并的时候,需要比较两颗待合并子树的秩,因此可以顺带的将对秩的最大值的更新也放在这里进行. 注意当n为0 时,输出为1 。
#include<cstdio> #define N 100001 int father[N],sz[N],max; int find(int x) { if(x==father[x]) return x; father[x]=find(father[x]); return father[x]; } void Union(int x,int y) { int a=find(x); int b=find(y); if(a==b) return; if(sz[a]>sz[b]) { father[b]=a; sz[a]+=sz[b]; if(sz[a]>max) { max=sz[a]; } } else { father[a]=b; sz[b]+=sz[a]; if(sz[b]>max) max=sz[b]; } } int main() { int n,a,b,i; while(scanf("%d",&n)!=EOF) { for(i=1;i<=n;i++) { father[i]=i; sz[i]=1; } max=1; //输入0 时输出是 1 for(i=1;i<=n;i++) { scanf("%d%d",&a,&b); Union(a,b); } printf("%d\n",max); } return 0; }
原文地址:http://blog.csdn.net/u012773338/article/details/38776575