poj 并查集
http://poj.org/problem?id=1611
水题
题意:就是找一共有多少个人感染了,0是感染学生的编号。
#include <stdio.h>
#include <string.h>
#define maxn 30005 int m,n;
int belg[ maxn ]; int Find(int x)
{
int _x=x,_b;
while( _x != belg[ _x ] )
_x = belg[ _x ];
while( x != belg[ x ] )
{
_b = belg[ x ];
belg[ x ] = _x;
x = _b;
}
return _x;
} void unio(int x,int y)
{
int root1 = Find(x);
int root2 = Find(y);
if( root1 != root2 ) belg[root2] = root1;
} int main()
{
// freopen("in.txt","r",stdin);
int a,b,c,ans;
while(scanf("%d%d",&m,&n),m||n)
{
for( int i = ; i <= m ; i++ )
belg[ i ] = i;
for( int i = ; i < n ; i++ )
{
scanf("%d%d",&a,&b);
for( int j = ; j < a- ; j++ )
{
scanf("%d",&c);
unio(b,c);
}
}
ans = ;
a = Find();
for(int i = ; i <= m ; i++ )
if(Find(i)==a) ans++;
printf("%d\n",ans);
}
return ;
}
poj 2492
http://poj.org/problem?id=2492
题意:给出m组关系,要你判断这里面有没有同性恋。
这是并查集的一个高级用法,但是我是第一次用并查集的高级用法,现在也还不是很理解这是为什么,什么意思。还得好好的模拟,想一想,感觉身体被掏空
#include <stdio.h>
#include <string.h>
#define maxn 5005 int belg[ maxn ];
bool kind[ maxn ],sign; int Find(int x, bool &s)
{
int _x, h = x;
bool s1, s2; while ( belg[h]!=h )
{
s = s^kind[h]; //这里的目的是看s也就是当前的x是不是与他的祖父是相同性别的。 h = belg[h];
} s1 = s;
while ( belg[x]!=x )
{
_x = belg[x];
belg[x] = h;
s2 = kind[x];
kind[x] = s1; //更新kind[ x ],因为最开始的x的kind就是s1,而之后的kind[ x ]就应该是s1与s2的^运算 s1 = s1^s2;
x = _x;
} return h;
} void unio(int x,int y)
{
bool su,sv;
int root1 = Find( x ,sv=false);
int root2 = Find( y ,su=false);
if( root1 == root2 ) sign = sv^su;
else {
belg[ root2 ] = root1;
kind[ root2 ] = !(su^sv);
}
} int main()
{
freopen("in.txt","r",stdin);
int t,nu = ,a,b,m,n;
scanf("%d",&t);
while(t--)
{
sign = true;
nu++;
scanf("%d%d",&m,&n);
memset( kind , false , sizeof( kind ) );
for( int i = ; i <= m ; i++ )
belg[ i ] = i;
for( int i = ; i < n ; i++ )
{
scanf("%d%d",&a,&b);
if(sign) unio(a,b);
}
printf("Scenario #%d:\n",nu);
if(sign)
printf("No suspicious bugs found!\n\n");
else
printf("Suspicious bugs found!\n\n"); }
return ;
}
poj 2498
poj 1988
http://poj.org/problem?id=1988
题意:就是给你一群盒子,有两个操作,M就是move,也就是把x盒子移到y盒子的上面。
c就是查询,查询x下面一共有多少个盒子
移动,是指x盒子及其上面的所有的盒子都一起移动到y盒子的上面去。
这个题我原来做过,那个时候不会并查集,然后就用一个结构体来记录其最下面的点,最上面的点,以及这个点下面一共有多少个盒子,然后每次维护。这样就是超时.......然后最近学了并查集,但因为对其理解还不是特别深,不是很会灵活应用,所有也不知道怎么用。最后还是看别人博客,理解别人的思路,再去自己写
思路:维护两个数组,一个是当前盒子下面一共有多少个盒子,以及自己最上面的盒子的个数。
#include <stdio.h>
#include <string.h>
#define maxn 100030 int belg[ maxn ],rank[ maxn ],top[ maxn ]; int Find(int x)
{
if(belg[x]!=x)
{
int fa = belg[x]; //每次压缩的时候,顺便更新当前点下面的合资数。
belg[x] = Find(fa);
rank[x] += rank[fa];
}
return belg[x];
} void uion(int x,int y)
{
int root1 = Find( x );
int root2 = Find( y );
if( root1 != root2 )
{
belg[ root1 ] = root2; //把x移到y的上面,以及更新x的下面的数量和y最上面的的数量。
rank[ root1 ] = top[ root2 ] + ;
top[ root2 ] += top[ root1 ]+;
} } int main()
{
// freopen("in.txt","r",stdin);
int t,a,b;
char x;
scanf("%d",&t);
for(int i = ; i <= t ; i++)
belg[ i ] = i;
while(t--)
{
scanf("%s",&x);
if(x=='M')
{
scanf("%d%d",&a,&b);
uion( a , b );
}
else
{
scanf("%d",&a);
Find( a );
printf("%d\n",rank[ a ] );
}
}
return ;
}
poj 1988
poj 2912
http://poj.org/problem?id=2912
题意:有n个人在玩石头剪刀布,这其中就有一个是裁判,而且每一个人都只会出一种手势,要你求是否可以判断出裁判是哪个,并且输出在第几个语句可以判断。
这个题有点像那个食物链的题目,我在判断语句时,也是采取了和食物链一样的写法。
思路:就是枚举每一个人当为裁判,然后进行判断,看看其他与这个裁判无关的语句,是否有矛盾,如果没有矛盾,说明这个人有可能是裁判,如果有,那么这个人就肯定不能当裁判,最后如果没有符合条件的,就输出impossible,如果超过了一个人就输出Can not determine,如果恰好是一个人就输出可以找到,并且把裁判和在哪个语句中可以判断出,在哪个语句中可以判断出的话,这个就是在看最后一个产生矛盾的语句是在哪产生的,因为但枚举的不是这个裁判的时候,这个裁判的语句就会被合并,当找到最后一个矛盾产生的语句时,也就可以判断这个裁判是在哪里被找出来的了。
关于那些语句看不懂可以先去看看我写的食物链。Poj 1182
http://www.cnblogs.com/Tree-dream/p/5709880.html
#include <stdio.h>
#include <string.h>
#define maxn 2005 struct note{
int x,mark,y;
}s[ maxn ]; int m,n,belg[ maxn * ];
bool mark[ maxn * ]; int Find(int x)
{
int _x=x,_b;
while(_x!=belg[_x])
{
_x=belg[_x];
}
while(x!=belg[x])
{
_b=belg[x];
belg[x]=_x;
x=_b;
}
return _x;
} bool judge(int x,int y) {
if(Find(x)==Find(y))
return true;
else return false;
} void unite(int x,int y)
{
int root1=Find(x);
int root2=Find(y);
if(root1!=root2) belg[root1]=root2;
} void init()
{
for( int i = ; i <= *m ; i++ )
belg[ i ] = i;
} int main()
{
// freopen("in.txt","r",stdin);
int a,b;
char c;
while(scanf("%d%d",&m,&n)!=EOF)
{
init();
for(int i = ; i <= n ; i++ )
{
scanf("%d%c%d",&a,&c,&b);
getchar();
if(c=='=')
{
s[ i ].x = a;
s[ i ].y = b;
s[ i ].mark = ;
}
if(c=='<')
{
s[ i ].x = b;
s[ i ].y = a;
s[ i ].mark = ;
}
if(c=='>')
{
s[ i ].x = a;
s[ i ].y = b;
s[ i ].mark = ;
}
}
int i,sign = ,falg = ,y = ,j;
for( i = ; i < m ; i++ )
{
init();
for(j = ;j <= n ; j++ )
{
if(s[ j ].x != i && s[ j ].y != i)
{
if(s[ j ].mark == )
{
if(judge(s[ j ].x,s[ j ].y + m )||judge(s[ j ].x,s[ j ].y + * m))
{
if( j > y ) y = j;
break;
}
else
{
unite(s[ j ].x , s[ j ].y);
unite(s[ j ].x + m , s[ j ].y + m);
unite(s[ j ].x + * m , s[ j ].y + * m);
}
}
else
{
if(judge( s[ j ].x , s[ j ].y)||judge(s[ j ].x , s[ j ].y + * m))
{ if( j > y ) y = j;
break;
}
else
{
unite( s[ j ].x , s[ j ].y + m );
unite( s[ j ].x + m , s[ j ].y + * m );
unite( s[ j ].x + * m , s[ j ].y );
}
}
}
}
if(j == n+)
{
falg ++;
sign = i;
}
}
if(falg == ) printf("Impossible\n");
else if(falg > ) printf("Can not determine\n");
else printf("Player %d can be determined to be the judge after %d lines\n",sign,y); }
return ;
}
poj 2912
HDU 3038
题意:n次询问,给出a到b区间的总和,问这n次给出的总和中有几次是和前面已近给出的是矛盾的。
思路:并查集,维护一个之间和的序列就可以。
#include <stdio.h>
#include <string.h>
#define maxn 200020 int belg[ maxn ],sum[ maxn ]; int Find(int x)
{
if(x!=belg[x])
{
int fa = belg[ x ];
belg[ x ] = Find(fa);
sum[ x ] += sum[ fa ];
}
return belg[ x ];
} int main()
{
// freopen("in.txt","r",stdin);
int m,n,a,b,c; while(scanf("%d%d",&m,&n)!=EOF)
{
int ans=;
for( int i = ; i <= m ; i++ )
belg[ i ] = i,sum[ i ] = ;
for( int i = ; i < n ; i++ )
{
scanf("%d%d%d",&a,&b,&c);
b--; //这里记得--
int root1 = Find(a),root2 = Find(b);
if(root1 == root2)
{
if(sum[ b ]-sum[ a ] != c) ans++;
}
else
{
belg[ root2 ] = root1;
sum[ root2 ] = sum[ a ]- sum[ b ] + c;
}
}
printf("%d\n",ans);
}
return ;
}
hdu 3038
poj 并查集的更多相关文章
- [并查集] POJ 1703 Find them, Catch them
Find them, Catch them Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 43132 Accepted: ...
- [并查集] POJ 2236 Wireless Network
Wireless Network Time Limit: 10000MS Memory Limit: 65536K Total Submissions: 25022 Accepted: 103 ...
- poj 1797(并查集)
http://poj.org/problem?id=1797 题意:就是从第一个城市运货到第n个城市,最多可以一次运多少货. 输入的意思分别为从哪个城市到哪个城市,以及这条路最多可以运多少货物. 思路 ...
- poj 2524 (并查集)
http://poj.org/problem?id=2524 题意:在一所学校里面的人,都有宗教信仰,不过他们的宗教信仰有可能相同有可能不同,但你又不能直接去问他们,但你可以问他们和谁是同一个宗教.通 ...
- poj 2236:Wireless Network(并查集,提高题)
Wireless Network Time Limit: 10000MS Memory Limit: 65536K Total Submissions: 16065 Accepted: 677 ...
- poj 1182:食物链(种类并查集,食物链问题)
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 44168 Accepted: 12878 Description ...
- [POJ 1988] Cube Stacking (带值的并查集)
题目链接:http://poj.org/problem?id=1988 题目大意:给你N个方块,编号从1到N,有两种操作,第一种是M(x,y),意思是将x所在的堆放到y所在的堆上面. 第二种是C(x) ...
- POJ 1456 Supermarket 区间问题并查集||贪心
F - Supermarket Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Sub ...
- POJ 2492 并查集扩展(判断同性恋问题)
G - A Bug's Life Time Limit:10000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u S ...
随机推荐
- NOI2018准备Day12
上午学了1个小时左右的指针,学了个从句子中分离单词的方法,其他的感觉没学到啥. 中午看了一会儿网络流,懵逼...... A了8道题,4道钻石.3道黄金.1道白银,自己写出了codevs"解药 ...
- 潭州学院-JavaVIP的Javascript的高级进阶-KeKe老师
潭州学院-JavaVIP的Javascript的高级进阶-KeKe老师 讲的不错,可以学习 下面是教程的目录截图: 下载地址:http://www.fu83.cn/thread-283-1-1.htm ...
- 析构函数virtual与非virtual区别 [转]
作为通常的原则,如果一个类定义了虚函数,那么它的析构函数就应当是virtual的.因为定义了虚函数则隐含着:这个类会被继承,并且会通过基类的指针指向子类对象,从而得到多态性. 这个类可能会被继承, ...
- JS组件系列——表格组件神器:bootstrap table(二:父子表和行列调序)
前言:上篇 JS组件系列——表格组件神器:bootstrap table 简单介绍了下Bootstrap Table的基础用法,没想到讨论还挺热烈的.有园友在评论中提到了父子表的用法,今天就结合Boo ...
- NDK开发之一
2015.07.22 Wiki_Tree: --NDK开发: --NDK特征: --MK文件编写规则: NDK开发: Ndk-build编译时会生成的两个同名的so库,位于不同的目录/project ...
- kuangbin专题总结一 简单搜索
A - 棋盘问题:在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有 ...
- java中hashcode()和equals()的详解
今天下午研究了半天hashcode()和equals()方法,终于有了一点点的明白,写下来与大家分享(zhaoxudong 2008.10.23晚21.36). 1. 首先equals()和hashc ...
- hibernate通过xml配置文件实现表与实体的映射
这里讨论的是一对多的关系 在做公交卡系统,会涉及到两张表,忽略两种表的作用,只关心他们之间的关系 : 卡规格表和卡类表,一种卡规格会对应多个卡类 实体类: /** * 卡类型表的实体 */ publi ...
- ScrollView中嵌套recycleView 出现的不显示,显示不全,终极解决方案
最近公司项目中用到了ScrollView去嵌套recycleView, 最开始我天真的把recycleView直接放入scrollView中,结果可想而知,什么都不显示,瞬间懵逼,我心想应该是和嵌套L ...
- C++链表
之前用C写链表的时候,结点使用结构体封装的,操作起来总是感觉很麻烦.C++中使用类来封装结点,感觉操作起来方便多了,内存回收也感觉很清楚. 最近,做Gps数据分析时,别人要求加一个树形控件. Gps数 ...