码迷,mamicode.com
首页 > 其他好文 > 详细

BNU 51275 道路修建 Large 并查集

时间:2016-02-09 12:02:43      阅读:291      评论:0      收藏:0      [点我收藏+]

标签:

分析(引入Q神题解  %%%Q)

如果使用可持久化并查集,二分答案判定连通性,复杂度是O(mlog3n),不能在时限内出解。
考虑到并查集实际上是一棵树,可以尝试在边上维护一些信息,假设t时刻加了一条边(u,v),若u和v此时未连通,
则在root(u)和root(v)之间连一条权值为t的边,表示u所在集合以及v所在集合在t时刻连通,
这样对于一组查询(u,v),如果u和v位于同一个连通块内,只需找出并查集中u到v的路径上的权值最大值,
很显然这样是不能路径压缩的,但是可以按秩合并保证树高是O(logn),总的复杂度是O(mlogn)。

这样找到树根是logn,路径查询也是logn 总的是mlogn,关键是代码很好写

 

技术分享
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long LL;
const int N=1e5+5;
int fa[N],r[N],p[N],vis[N],n;
void init()
{
   for(int i=1;i<=n;++i)
   {
      fa[i]=i;
      p[i]=r[i]=0;
      vis[i]=-1;
   }
}
int find(int x)
{
    if(x==fa[x])return x;
    return find(fa[x]);
}
bool Union(int u,int v,int t)
{
    u=find(u);
    v=find(v);
    if(u==v)return false;
    if(r[u]>r[v])
    {
       fa[v]=u;
       p[v]=t;
    }
    else
    {
       fa[u]=v;
       p[u]=t;
       if(r[u]==r[v])++r[v];
    }
    return true;
}
int getans(int u,int v)
{
    int now=0,x=u,ans;
    while(1)
    {
       vis[x]=now;
       if(x==fa[x])break;
       now=max(now,p[x]);
       x=fa[x];
    }
    x=v,now=0;
    while(1)
    {
       if(vis[x]!=-1)
       {
           now=max(now,vis[x]);
           ans=now;
           break;
       }
       now=max(now,p[x]);
       x=fa[x];
    }
    x=u;
    while(1)
    {
       vis[x]=-1;
       if(x==fa[x])break;
       x=fa[x];
    }
    return ans;
}
int main()
{
    int T,la,m;
    scanf("%d",&T);
    while(T--)
    {
       scanf("%d%d",&n,&m);
       init(),la=0;
       int op,u,v,blk=n;
       for(int i=1;i<=m;++i)
       {
          scanf("%d%d%d",&op,&u,&v);
          u^=la,v^=la;
          if(op)
          {
              int x=find(u);
              int y=find(v);
              if(x!=y)
                  la=0;
              else la=getans(u,v);
              printf("%d\n",la);
          }
          else
          {
              if(Union(u,v,i))blk--;
              la=blk;
              printf("%d\n",la);
          }
       }
    }
    return 0;
}
View Code

 

BNU 51275 道路修建 Large 并查集

标签:

原文地址:http://www.cnblogs.com/shuguangzw/p/5185482.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!