并查集
题意:找出给定的这些话中是否有冲突。若没有则最多有多少句是对的。
/*
思路:如果第x句说y是对的,则x,y必定是一起的,x+n,y+n是一起的;反之x,y+n//y,x+n是一起的。
利用并查集判断 x 和 x+n 是否在同一集合。
至于查找最多正确的话,对这些 “小树” 进行dfs即可。
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<queue>
#include<map>
#include<stack>
#include<set>
#include<math.h>
using namespace std;
typedef long long int64;
//typedef __int64 int64;
typedef pair<int64,int64> PII;
#define MP(a,b) make_pair((a),(b))
const int maxn = 2005;
const int inf = 0x7fffffff;
const double pi=acos(-1.0);
const double eps = 1e-8;
int fa[ maxn ];
int rank[ maxn ];
struct Edge{
int u,v,next;
}edge[ maxn<<1 ];
int cnt,head[ maxn ];
int vis[ maxn ];
int Cnt_true,Cnt_false;
void init( int n ){
cnt = 0;
//Cnt_true = Cnt_false = 0;
memset( head,-1,sizeof( head ) ) ;
for( int i=1;i<=n;i++ ){
fa[ i ] = i;
rank[ i ] = 1;
vis[ i ] = 0;
}
}
void addedge( int a,int b ){
edge[ cnt ].u = a;
edge[ cnt ].v = b;
edge[ cnt ].next = head[ a ];
head[ a ] = cnt ++ ;
edge[ cnt ].u = b;
edge[ cnt ].v = a;
edge[ cnt ].next = head[ b ];
head[ b ] = cnt ++ ;
}
int find( int x ){
if( x==fa[x] )
return x;
return fa[x] = find( fa[x] );
}
void union_ab( int x,int y ){
int fax = find( x );
int fay = find( y );
if( rank[ fax ]>rank[ fay ] ){
fa[ fay ] = fax;
rank[ fax ] += rank[ fay ];
}
else {
fa[ fax ] = fay;
rank[ fay ] += rank[ fax ];
}
}
void dfs( int x,int n ){
vis[ x ] = 1;
if( x<=n ){
vis[ x+n ] = 1;
Cnt_true ++ ;
//若x是正确的,则x+n则是错误的,同时也不用再去访问。
}
else {
vis[ x-n ] = 1;
Cnt_false ++ ;
}
for( int i=head[x];i!=-1;i=edge[i].next ){
int y = edge[i].v;
if( !vis[y] ){
dfs( y,n );
}
}
}
int main(){
int n;
while( scanf("%d",&n)==1,n ){
init( n*2 );
bool f = true;
char s1[ 24 ],s2[ 24 ],s3[ 24 ];
int x1,y1,x2,y2;
int fax,fay;
for( int i=1;i<=n;i++ ){
scanf("%s%d%s%s",s1,&y1,s2,s3);
x1 = i,x2 = i+n;
y1 = y1,y2 = y1+n;
//x1表示true,x2表示false
if( f==false ) continue;
if( s3[0]=='f' ){
fax = find( x1 );
fay = find( y1 );
if( fax==fay ){
f = false;
continue;
}
fax = find( x2 );
fay = find( y2 );
if( fax==fay ){
f = false;
continue;
}
union_ab( x1,y2 );
union_ab( x2,y1 );
addedge( x1,y2 );
addedge( x2,y1 );
}
else {
fax = find( x1 );
fay = find( y2 );
if( fax==fay ){
f = false;
continue;
}
fax = find( x2 );
fay = find( y1 );
if( fax==fay ){
f = false;
continue;
}
union_ab( x1,y1 );
union_ab( x2,y2 );
addedge( x1,y1 );
addedge( x2,y2 );
}
}
if( f==false ) {
puts("Inconsistent");
continue;
}//specail judge
for( int i=1;i<=n;i++ ){
if( find(i)==find(i+n) ){
f = false;
break;
}
}
if( f==false ) {
puts("Inconsistent");
continue;
}
int ans = 0;
for( int i=1;i<=2*n;i++ ){
if( !vis[i] ){
Cnt_false = Cnt_true = 0;
dfs( i,n );
ans += max( Cnt_true,Cnt_false );
}
}//find the max
printf("%d\n",ans );
}
return 0;
}
分享到:
相关推荐
- 并查集用于处理不相交集合的合并及查询问题。 3. **哈希表** - 推荐题目:[poj3349](https://vjudge.net/problem/POJ-3349)、[poj3274](https://vjudge.net/problem/POJ-3274)、[POJ2151]...
一种常见的方法是使用深度优先搜索(DFS)或广度优先搜索(BFS)来构建线段之间的连接,并通过并查集(Disjoint Set)数据结构来判断是否存在不相交的集合。 1. **数据结构**:首先,我们需要用数组或者链表存储...
并查集** - **定义**:一种用于处理一些不交集的合并及查询问题的数据结构。 - **示例题目**: - poj1703 - poj1988 - poj2524 - poj2492 - **应用场景**:适用于图论中的连通性问题。 **4. 哈希表和二分查找*...
- **注意事项**: 掌握并查集的合并和查找操作。 **4. 哈希表** - **定义**: 使用哈希函数将元素映射到数组索引上的数据结构。 - **应用场景**: 快速查找。 - **示例题目**: POJ 3349, POJ 3274, POJ 2151, POJ ...
- 并查集:处理不相交集合问题,如POJ3349。 - 哈希表和二分查找:提高查找效率,如POJ2151。 - 哈夫曼树:用于数据压缩,如POJ3253。 - 堆:如POJ2299。 - Trie树:快速查找前缀,如POJ2513。 4. **搜索算法*...
- **内容**: 并查集是一种支持并操作和查找操作的数据结构。 - **示例题目**: poj3253 - **知识点**: - **并操作**:将两个集合合并成一个集合。 - **查找操作**:查询某个元素所在的集合。 ### 四、字符串 ####...
3. **并查集**:用于处理不相交集合的问题(poj1195, poj3321)。 4. **区间查询**:如RMQ问题(poj3264, poj3368)。 5. **字符串匹配**:如KMP算法(poj1961, poj2406)。 ### 十三、进阶算法 1. **组合优化**:...
Prim算法和Kruskal算法分别基于贪心策略和并查集数据结构,用于在带权图中找到连接所有顶点的最小总权重的树结构。 #### 拓扑排序 适用于有向无环图,帮助分析任务依赖关系,如poj1094所示。 #### 匹配算法 包括...
poj1035、poj3080等训练了串的操作,poj2388、poj2299等则涉及排序问题,poj2524、poj1611等是并查集的实例,poj3349、poj3274等展示了哈希表和二分查找,poj3253是哈夫曼树的题目,poj2442和poj1442则关于堆。...
- **并查集**:处理集合连接与查询,如 poj3026。 - **哈希表** 和 **二分查找**:提高查找效率,如 poj3349、poj3274。 - **哈夫曼树**:压缩编码,如 poj3253。 - **堆**:用于优先队列和最值问题。 - **Trie...
对于没有父节点指针的普通二叉树,解决LCA的方法通常涉及到深度优先搜索(DFS)。我们可以从根节点开始,找到给定节点的路径,并存储在向量中。例如,假设我们有以下二叉树: ``` 10 / \ 6 14 / \ / \ 4 8 12 16 ...
- **并查集**:掌握其基本操作和应用。 - **哈希表和二分查找**:利用这些高效查找方法,如Poj3349、Poj3274等。 - **哈夫曼树**:用于压缩编码和优化空间,如Poj3253。 - **堆**:学习堆的性质和操作,如优先...
- 高级数据结构:平衡树(AVL树、红黑树)、线段树、树状数组、并查集等。 - 特殊的数据结构:后缀数组、LCP数组等用于文本处理的高效结构。 #### 6. 几何题 几何题通常涉及到几何图形的性质、计算等。 - **知识点*...
3. 并查集:用于处理集合的合并与查询,如路径压缩和按秩合并。 4. 哈希表和二分查找:提供高效的查找操作,如POJ3349、POJ3274等。 5. 哈夫曼树:编码压缩,如POJ3253。 6. 堆:优先队列的实现,如最小堆和最大堆。...
推荐题目如1011、1033、1129、2049、2056、2488、2492等,其中2492可以考虑使用并查集解决。 3. **贪心**(Greedy) 贪心算法在每一步选择局部最优解,期望达到全局最优。推荐题目有1065、2054、1521、2709等,...
3. **并查集**:处理集合合并和查询问题。 4. **哈希表** 和 **二分查找**:提供高效查找能力,如POJ3349、3274、2151、1840、2002和2503。 5. **哈夫曼树**:用于压缩编码,如POJ3253。 6. **堆**:用于优先队列和...
并查集是一种用于管理一组元素分割成若干个不相交子集的数据结构。 3. **哈希表** - POJ 3349, POJ 3274, POJ 2151, POJ 1840, POJ 2002, POJ 2503 哈希表是一种实现关联数组的数据结构,可以快速插入、删除和...
数据结构是解决问题的基础工具,包括串、排序(快速排序、归并排序、堆排序)、并查集、哈希表、二分查找以及哈夫曼树和堆。poj1035、poj3080和poj1936是关于串的问题,poj2388和poj2299则是排序算法的实践,poj3349...
9. **数据结构**:并查集、堆等数据结构的应用,如1002使用快速排序,1007要求稳定的排序算法,2231则可能涉及二叉排序树。 10. **博弈论**:博弈论题目如1002,需要理解博弈过程并找到最优策略。 此外,还有历法...
3. 并查集:处理集合合并与查询,如poj3349。 4. 哈希表和二分查找:快速查找,如poj3274、poj2151等。 5. 哈夫曼树:用于压缩编码,如poj3253。 6. 堆:优先队列实现,如poj1459。 7. Trie树:用于高效字符串查询,...