数据分割-并查集+set

小w来到百度之星的赛场上,准备开始实现一个程序自动分析系统。
这个程序接受一些形如xi=xj 或 xi≠xj
的相等/不等约束条件作为输入,判定是否可以通过给每个 w 赋适当的值,来满足这些条件。

输入包含多组数据。
然而粗心的小w不幸地把每组数据之间的分隔符删掉了。
他只知道每组数据都是不可满足的,且若把每组数据的最后一个约束条件去掉,则该组数据是可满足的。
请帮助他恢复这些分隔符。
Input
第1行:一个数字L,表示后面输入的总行数。
之后L行,每行包含三个整数,i,j,e,描述一个相等/不等的约束条件,若e=1,则该约束条件为xi=xj ,若e=0,则该约束条件为 xi≠xj 。
i,j,L≤100000 xi,xj≤L
Output
输出共T+1行。
第一行一个整数T,表示数据组数。
接下来T行的第i
行,一个整数,表示第i组数据中的约束条件个数。
Sample Input
6
2 2 1
2 2 1
1 1 1
3 1 1
1 3 1
1 3 0
Sample Output
1
6

看起来就是一个并查集。可是对于不相等的关系,我们只能暴力保存。刚开始我用了一个数组表保存,相等关系的时候都查询一次有没有和之前的不等关系冲突。成功超时。

看题解了解到要用set,的确用set的话查找操作更加方便,空间复杂度也更好。

对每个节点都建立一个set,用于保存不能和他们相等的元素。随着相等元素的增多,我们也得同时合并他们的不等元素。将这些元素都保存在并查集的根节点处,合并的时候根据这个set的大小进行合并,尽量是小的合并到大的里面。注意在将set中的元素插入到另一个set中时,需要将该元素所指向元素中的set的值全部修改(相当于修改他们的代表,换老大了)

再建立一个set用于记录出现过的节点,这样就不用memset恢复并查集数组了。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<climits>
#include<algorithm>
#include<ctime>
#include<cstdlib>
#include<queue>
#include<set>
#include<map>
#include<cmath>using namespace std;const int MAXN=1e5+5;
int Equal[MAXN];
int L,T,len;
set<int> un[MAXN],st;
int tot=0;
int ans[MAXN];int find(int x)
{if(Equal[x]==0){Equal[x]=x; return x;}if(x==Equal[x]) return x;int t=x;while(t!=Equal[t]) t=Equal[t];int y=x,z;while(Equal[y]!=t){z=Equal[y]; Equal[y]=t; y=z;}return t;
}void Union(int x,int y)
{if(un[x].size()>un[y].size()) swap(x,y);set<int>::iterator it;for(it=un[x].begin();it!=un[x].end();it++){un[*it].erase(x);un[*it].insert(y);un[y].insert(*it);}Equal[x]=y;
}int main()
{T=0; len=0;int u,v,w;bool wrong=false;scanf("%d",&L);set<int>::iterator it;while(L--){len++;scanf("%d%d%d",&u,&v,&w);st.insert(u); st.insert(v);int rt1=find(u),rt2=find(v);if(w==1){if(rt1==rt2){continue;}else{if(un[rt1].count(rt2)==0){Union(rt1,rt2);}else{wrong=true;}}}else{if(rt1==rt2){wrong=true;}else{un[rt1].insert(rt2);un[rt2].insert(rt1);}}if(wrong){for(it=st.begin();it!=st.end();it++){Equal[*it]=*it;un[*it].clear();}st.clear();ans[++T]=len;len=0;tot=0;wrong=false;}}printf("%d\n",T);for(int i=1;i<=T;i++){printf("%d\n",ans[i]);}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/383765.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux c++线程池的实现

http://blog.csdn.net/zhoubl668/article/details/8927090?t1473221020107 线程池的原理大家都知道&#xff0c;直接上代码了^_^ Thread.h [cpp] view plaincopy #ifndef __THREAD_H #define __THREAD_H #include <vector> #include <string> #inc…

树启发式合并入门

所谓启发式合并&#xff0c;就是一种符合直觉的合并方法&#xff1a;将小的子树合并在大的子树上。 这些问题一般是相似的问题背景&#xff1a;都是树上的计数问题&#xff0c;都不能直接从上往下进行暴力&#xff0c;都需要从下往上计数时对子树信息进行运算从而得到父亲节点的…

链栈基本操作

http://blog.csdn.net/jwentao01/article/details/46765517###;栈基本概念&#xff1a; 栈&#xff08;stack&#xff09;是限定在表尾进行插入和删除操作的线性表&#xff08;或单链表&#xff09;。 //只能在一段进行插入和删除&#xff0c;因此不存在&#xff0c;在中间进行…

Linux网络编程---I/O复用模型之select

https://blog.csdn.net/men_wen/article/details/53456435Linux网络编程—I/O复用模型之select 1. IO复用模型 IO复用能够预先告知内核&#xff0c;一旦发现进程指定的一个或者多个IO条件就绪&#xff0c;它就通知进程。IO复用阻塞在select或poll系统调用上&#xff0c;而不是阻…

UVa12633-Super Rooks on Chessboard-容斥+FFT

题目大意就是给你一个R*C的棋盘&#xff0c;上面有超级兵&#xff0c;这种超级兵会攻击 同一行、同一列、同一主对角线的所有元素&#xff0c;现在给你N个超级兵的坐标&#xff0c;需要你求出有多少方块是不能被攻击到的(R,C,N<50000) 遇到这种计数问题就要联想到容斥&#…

Linux网络编程---I/O复用模型之poll

https://blog.csdn.net/men_wen/article/details/53456474Linux网络编程—I/O复用模型之poll 1.函数poll poll系统调用和select类似&#xff0c;也是在指定时间内轮询一定数量的文件描述符&#xff0c;以测试其中是否有就绪者。 #include <poll.h>int poll(struct pollfd…

FFT模板

整理了一下&#xff0c;自己写了一下模板 const double PIacos(-1.0); struct complex {double r,i;complex(double _r0,double _i0):r(_r),i(_i){}complex operator (const complex &b) {return complex(rb.r,ib.i);}complex operator -(const complex &b) {return c…

Linux网络编程---I/O复用模型之epoll

https://blog.csdn.net/men_wen/article/details/53456474 Linux网络编程—I/O复用模型之epoll 1. epoll模型简介 epoll是Linux多路服用IO接口select/poll的加强版&#xff0c;e对应的英文单词就是enhancement&#xff0c;中文翻译为增强&#xff0c;加强&#xff0c;提高&…

POJ 1741tree-点分治入门

学习了一下点分治&#xff0c;如果理解有误还请不吝赐教。 为了快速求得树上任意两点之间距离满足某种关系的点对数&#xff0c;我们需要用到这种算法。 点分治是树上的一种分治算法&#xff0c;依靠树和子树之间的关系进行分治从而降低复杂度。 和其他树上的算法有一些区别…

基于单链表的生产者消费者问题

『生产者与消费者问题分析』「原理」生产者生产产品&#xff0c;消费者消费产品。产品如果被消费者消费完了&#xff0c;同时生产者又没有生产出产品&#xff0c;消费者 就必须等待。同样的&#xff0c;如果生产者生产了产品&#xff0c;而消费者没有去消费&#x…

C++智能指针(一)智能指针的简单介绍

https://blog.csdn.net/nou_camp/article/details/70176949C智能指针 在正式了解智能指针前先看一下下面的一段代码 #include<iostream> using namespace std; class A { public:A():_ptr(NULL), _a(0){}~A(){} public:int* _ptr;int _a; };void test() {A a;int *p1 ne…

聪聪可可-点分治

聪聪和可可是兄弟俩&#xff0c;他们俩经常为了一些琐事打起来&#xff0c;例如家中只剩下最后一根冰棍而两人都想吃、两个人都想玩儿电脑&#xff08;可是他们家只有一台电脑&#xff09;……遇到这种问题&#xff0c;一般情况下石头剪刀布就好了&#xff0c;可是他们已经玩儿…

C++智能指针(二)模拟实现三种智能指针

https://blog.csdn.net/nou_camp/article/details/70186721在上一篇博客中提到了Auto_ptr(C智能指针&#xff08;一&#xff09;)&#xff0c;下面进行模拟实现Auto_ptr 采用类模板实现 #include<iostream> using namespace std; template<class T> class Autoptr …

Prime Distance On Tree-树分治+FFT

题目描述 Problem description. You are given a tree. If we select 2 distinct nodes uniformly at random, what’s the probability that the distance between these 2 nodes is a prime number? Input The first line contains a number N: the number of nodes in this…

C++智能指针(三)总结

https://blog.csdn.net/nou_camp/article/details/70195795 在上一篇博客中&#xff08;C智能指针&#xff08;二&#xff09;&#xff09;模拟实现了三种智能指针。 其中最好的就是shared_ptr,但是这并不代表它就是最完美的&#xff0c;它也有问题&#xff0c;这个问题就是循环…

POJ2114-Boatherds-树分治

题目描述 Boatherds Inc. is a sailing company operating in the country of Trabantustan and offering boat trips on Trabantian rivers. All the rivers originate somewhere in the mountains and on their way down to the lowlands they gradually join and finally th…

c++11 你需要知道这些就够了

https://blog.csdn.net/tangliguantou/article/details/50549751c11新特性举着火把寻找电灯今天我就权当抛砖引玉&#xff0c;如有不解大家一起探讨。有部分内容是引用自互联网上的内容&#xff0c;如有问题请联系我。T&& 右值引用 std::move 右值引用出现之前我们只能…

HDU5977-Garden of Eden-树分治+FWT

题目描述 When God made the first man, he put him on a beautiful garden, the Garden of Eden. Here Adam lived with all animals. God gave Adam eternal life. But Adam was lonely in the garden, so God made Eve. When Adam was asleep one night, God took a rib fro…

C++11新特性学习

https://blog.csdn.net/tennysonsky/article/details/778170481、什么是C11C11标准为C编程语言的第三个官方标准&#xff0c;正式名叫ISO/IEC 14882:2011 - Information technology -- Programming languages -- C。在正式标准发布前&#xff0c;原名C0x。它将取代C标准第二版I…

C++ override 关键字用法

override关键字作用&#xff1a; 如果派生类在虚函数声明时使用了override描述符&#xff0c;那么该函数必须重载其基类中的同名函数&#xff0c;否则代码将无法通过编译。举例子说明struct Base {virtual void Turing() 0;virtual void Dijkstra() 0;virtual void VNeumann…