UVA 11987 - Almost Union-Find
第一次交TLE,说好的并查集昂。
好吧我改。求和、个数 在各个步骤独立算。。
还是TLE。
看来是方法太慢,就一个数组(fa),移动的话,移动跟结点要遍历一次 T T
嗯,那就多一个数组。
0.189S。
#include<cstdio> const int MAXN=100000+10; int fa[MAXN],num[MAXN],idx[MAXN],cnt,n,m; long long sum[MAXN]; int find(const int & x) //查找父结点,顺带路径压缩 { return fa[x]==x? x: fa[x]=find(fa[x]); } inline void init() { for(int i=1;i<=n;i++) { fa[i]=idx[i]=sum[i]=i; num[i]=1; } cnt=n; } inline void Union() { int p,q; scanf("%d%d",&p,&q); int rootp=find(idx[p]); //找p的根节点 int rootq=find(idx[q]); if(rootp!=rootq) { fa[rootp]=rootq; sum[rootq]+=sum[rootp]; num[rootq]+=num[rootp]; } } inline void update(const int &p,const int &rootp) { sum[rootp]-=p; num[rootp]--; idx[p]=++cnt; sum[idx[p]]=p; num[idx[p]]=1; fa[idx[p]]=idx[p]; } inline void move() { int p,q; scanf("%d%d",&p,&q); int rootp=find(idx[p]); //找p的根节点 int rootq=find(idx[q]); if(rootp!=rootq) { update(p,rootp); fa[idx[p]]=rootq; sum[rootq]+=p; num[rootq]++; } } inline void print() { int p; scanf("%d",&p); int rootp=find(idx[p]); printf("%d %lld\n",num[rootp],sum[rootp]); } int main() { while(scanf("%d%d",&n,&m)!=EOF) { init(); while(m--) { int action; scanf("%d",&action); switch(action) { case 1:Union();break; case 2:move();break; case 3:print();break; } } } }
新 blog : www.hrwhisper.me