并查集模板:

 #include<iostream>
using namespace std;
int Rank[],x,y;
int v[];
//初始化 x 集合
void init(int n)
{
for(int i=; i<n; i++)
{
v[i]=i;
Rank[i]=;
}
}
//查找 x 所在的集合
int find_set(int x)
{
if(v[x]!=x) v[x]=find_set(v[x]);
return v[x];
}
///更新根节点,有可能会暴栈
int mix(int x,int y)
{
int fx,fy;
fx=find_set(x);
fy=find_set(y);
if(fx!=fy)
p[fx]=fy;
}
//合并 x, y 所在的集合,用到路径压缩,按秩合并
void Union(int x,int y)
{
x=find_set(x);
y=find_set(y);
if(Rank[x]>Rank[y])
v[y]=x;
else if(Rank[x]<Rank[y])
v[x]=y;
else if(Rank[x]==Rank[y])
{
v[x]=y;
Rank[y]++;
}
}
int main()
{
return ;
}

模板

计算环的个数,需要缩点:

 #include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <sstream>
#include <algorithm>
#define maxn 100010
#define INF 0x7fffffff
#include <queue>
#define N 1000010
#define ll __int64
#define mem(a,b) memset(a,b,sizeof(a))
#define repu(i, a, b) for(int i = (a); i < (b); i++)
const double PI=-acos(-1.0);
using namesPce std;
///初始化 x 集合
int P[maxn],Rank[maxn];
void mix()
{
repu(i,,maxn)
{
P[i]=i;
Rank[i]=;
}
}
///查找 x 所在的集合
int find_set(int x)
{
if(P[x]!=x)
P[x]=find_set(P[x]);
return P[x];
}
///缩点,合并 x, y 所在的集合,用到路径压缩,按秩合并
void Union(int x,int y)
{
x=find_set(x);
y=find_set(y);
if(Rank[x]>Rank[y])
P[y]=x;
else if(Rank[x]<Rank[y])
P[x]=y;
else if(Rank[x]==Rank[y])
{
P[x]=y;
Rank[y]++;
}
}
int main()
{
int x,y;
while(scanf("%d",&x) == )
{
mix();
int refu = ;
while(x!=-)
{
scanf("%d",&y);
x = find_set(x);
y = find_set(y);
if(x == y)///如果同一个根节点,就是环
++refu;
else
Union(x,y);
scanf("%d",&x);
}
printf("%d\n",refu);
}
return ;
}

UVALA3644 find_set + Union

计算联通块的个数

题意:n个结点,m条边,求再连几条边能使得全部结点连通;

思路:并查集,求该图中有几个连通分支,然后连通块的个数-1;

 #include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
int p[];
int n,m;
int a,b;
int find_set(int x)
{
return p[x]==x?x:find_set(p[x]);
}
void mix(int x,int y)
{
int fx,fy;
fx=find_set(x);
fy=find_set(y);
if(fx!=fy)
p[fx]=fy;
}
int main()
{
int cas=;
while(scanf("%d",&n)&&n)
{
scanf("%d",&m);
int count=;
for(int i=; i<=n; i++)
p[i]=i;
for(int j=; j<=m; j++)
{
scanf("%d%d",&a,&b);
mix(a,b);
}
for(int i=; i<=n; i++)
if(p[i]==i) count++;
printf("%d\n",count-);
}
return ;
}

HDU 1232 find_set + mix

计算每个连通块个数,取最大:

 #include<cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
struct A
{
int num,pre;
} Set[];
void init(int n)///初始化
{
int i;
for(i=; i<=n; i++)
{
Set[i].num=;
Set[i].pre=i;
}
}
int Find(int k)///找根节点
{
if(Set[k].pre==k)
return k;
return Set[k].pre = Find(Set[k].pre);
}
int main()
{
int n,maxn,ans,i,f1,f2;
int x[],y[];
while(~scanf("%d",&n))
{
if(n==)
{
printf("1\n");
continue;
}
maxn=;
for(i=; i<=n; i++)
{
scanf("%d%d",&x[i],&y[i]);
maxn = max(maxn,max(x[i],y[i]));
}
init(maxn);
for(i=; i<=n; i++)
{
f1=Find(x[i]);
f2=Find(y[i]);
if(f1!=f2)
{
Set[f1].pre=f2;
Set[f2].num += Set[f1].num;///把该节点的子节点加上
}
}
ans=;
for(i=; i<=maxn; i++)
ans=max(ans,Set[i].num);
printf("%d\n",ans);
}
return ;
}

HDU 1856 find_set

简单并查集 -- HDU 1232 UVALA 3644 HDU 1856的更多相关文章

  1. 1213 How Many Tables(简单并查集)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1213 简单并查集,统计单独成树的数量. 代码: #include <stdio.h> #i ...

  2. POJ 2524 (简单并查集) Ubiquitous Religions

    题意:有编号为1到n的学生,然后有m组调查,每组调查中有a和b,表示该两个学生有同样的宗教信仰,问最多有多少种不同的宗教信仰 简单并查集 //#define LOCAL #include <io ...

  3. poj1611 简单并查集

    The Suspects Time Limit: 1000MS   Memory Limit: 20000K Total Submissions: 32781   Accepted: 15902 De ...

  4. 【简单并查集】Farm Irrigation

    Farm Irrigation Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Tot ...

  5. ACM_“打老虎”的背后(简单并查集)

    “打老虎”的背后 Time Limit: 2000/1000ms (Java/Others) Problem Description: “习大大”自担任国家主席以来大力反腐倡廉,各地打击贪腐力度也逐步 ...

  6. hdu 2480 贪心+简单并查集

    Steal the Treasure Time Limit: 10000/6000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  7. poj1988 简单并查集

    B - 叠叠乐 Crawling in process... Crawling failed Time Limit:2000MS     Memory Limit:30000KB     64bit ...

  8. UVA - 1197 (简单并查集计数)

    Severe acute respiratory syndrome (SARS), an atypical pneumonia of unknown aetiology, was recognized ...

  9. poj 2524 Ubiquitous Religions 一简单并查集

    Ubiquitous Religions   Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 22389   Accepted ...

随机推荐

  1. websphere如何删除应用程序服务器(概要管理工具)

    在IBM WebSphere 的概要管理工具中我们可以新建一个应用程序服务器,但是工具中并未提供删除已经建过的应用程序服务器.下面 交大家一个比较简单的方法来删除应用程序服务器 图片中可以看到,我已经 ...

  2. 【Linux命令与工具】ps命令

    Linux中的ps命令是Process Status的缩写.ps命令用来列出系统中当前运行的那些进程.ps命令列出的是当前那些进程的快照,就是执行ps命令的那个时刻的那些进程,如果想要动态的显示进程信 ...

  3. Ubuntu 14.04下安装功能强大的屏幕截图软件 Shutter

    [注释]试用了一下,果然很强大,牛逼 一款功能强大的屏幕截图软件——Shutter,Shutter最基本的就是截图功能了,在设计上可以自由选定区域,同时选定之 后依然可以通过上下左右四个地方来改变选区 ...

  4. 设置MySQL自动增长从某个指定的数开始

    自增字段,一定要设置为primary key. 以指定从1000开始为例.1 创建表的时候就设置: CREATE TABLE `Test` ( `ID` int(11) NOT NULL AUTO_I ...

  5. mysql 增删改查基本语句

    增: insert insert into 表名(字段1,字段2,字段3......字段N) values(值1,值2,值3): 如果不申明插入那些字段,则默认所有字段. 在插入时注意,往哪个表增加, ...

  6. gitlab open ssl

    cd /home/git/gitlab/ sudo -u git -H vi config/gitlab.yml sudo -u git -H vi /home/git/gitlab-shell/co ...

  7. 如何很好的使用Linq的Distinct方法

    Person1: Id=1, Name="Test1" Person2: Id=1, Name="Test1" Person3: Id=2, Name=&quo ...

  8. hdu4057Rescue the Rabbit(ac自动机+dp)

    链接 当时是因为没有做出来这道题才开了自动机的专题,现在看看还是比较简单的. 因为每个病毒串只算一次,只有10个病毒串,可以状压一下哪些状态是可以达到的,最后取一个最大值. #include < ...

  9. Android 实现闪屏页和右上角的倒计时跳转

    效果图: 闪屏页用到了handler和CountDownTimer类,还需配置一下Activity的主题,这里是:android:theme="@android:style/Theme.No ...

  10. 程序设计入门——C语言 第4周编程练习 2 念整数(5分)

    题目内容: 你的程序要读入一个整数,范围是[-100000,100000].然后,用汉语拼音将这个整数的每一位输出出来. 如输入1234,则输出: yi er san si 注意,每个字的拼音之间有一 ...