随笔分类 - DS——并查集
摘要:去你妹的并查集,没纠结死我!按速度排序,然后枚举所有的路,知道find(start) == find(end)结束。然后用最大值减去最小值,求其差,取差最小。Code:#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std;const int N = 1024;const int inf = 0x6fffffff;class node {public: int x, y,
阅读全文
摘要:/*发现并查集的应用太巧妙了。。。大体思路:从题中可以看出来如果(i, j)是even的话,sum(i-1) 和 sum(j)的奇偶性相同。(i, j)如果是odd的话则其奇偶行不同。定义奇偶性为朋友,不同则为敌人。这样按照奇偶性分成连个集合。same[i] = {x|sum[x]与sum[i]同奇偶}(即i的朋友集)diff[i] = {x|sum[x]与sum[i]不同奇偶}(即i的敌人集)如果(i, j)是even,则分别合并(same(i-1), same(j))和(dirr[i-1] , diff(j))。如果是odd,则因为不是奇就是偶,所以,一个的朋友和另一个的敌人合并(敌人..
阅读全文
摘要:/*思路参考大牛,我脑袋被lv踢了,居然想到用数状数组写。。。思路:并查集,先把不许要删的边用并查集合并,然后把需要删的边逆序加入到并查集中。。。。My Code:*/#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int N = 100005;struct node { int s; int e;}g[N];int parent[N];int c[N];int ans[N];int Rank[N];bool vis[N];void init(in
阅读全文
摘要:这两天搞dp搞的快暴了,想学学网络流。拿过算导来一看,最短路还没整完呢。写了一个用并查集优化的kruskal算法,并查集是用非递归的状态压缩实现的。详见:http://www.cnblogs.com/vongang/archive/2011/07/31/2122763.html。kruskal没有用堆优化,不是我不想,而是实在不会。。。所以直接用sort按权值排了下序,时间复杂度O(n+n*logn)My Code:#include <iostream>#include <cstdio>#include <cstring>#include <algor
阅读全文
摘要:/*贡献出无数WA, 就因为一个地方写错, 悲剧的一晚上啊!不过能过了还是很爽的。 思路:用Trie树给字符串重新标号,然后用并查集,用一个a[i] 记录当前并查集跟结点上连接的结点数。*/#include <iostream>#include <cstdio>#include <cstring>using namespace std;struct node{ int flag; node * next[53];};const int N = 200005;int parent[N];int rank[N];int a[N];int num;node * n
阅读全文
摘要:/*开始思路想错了,直接用并查集把输入的square并到并查集里边了,后来想到可能一种square连续出现多次,这样直接合并肯定会出问题的。然后就一直再想其他思路,昨晚睡觉时突然想到可以给这些square重新编号,把对应的square的pipes type继承过来,然后再用并查集合并。最终以6A告终。不容易啊,大牛鄙视我吧。*/#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int N = 3000;class pipes{ public: int
阅读全文
摘要:#include <iostream>#include <cstdio>#include <cstring>#pragma comment(linker,"/STACK:655360000");using namespace std;const int N = 1002;int f[N], rank[N];int find(int x){ int k, r, j; r = x; while(r != f[r]) { r = f[r]; } k = x; while(k != r) { j = f[k]; ...
阅读全文
摘要:并查集(Union-Find Sets),字面意思理解——合并,查找。给出一个集合,将其合并后用一个点代替一个集合的元素。例如:1 22 34 3合并后就是 2 / \1 3 \ 4主要操作:1、查找。2、合并。查找方法见http://www.cnblogs.com/vongang/archive/2011/07/31/2122763.html合并实现方法如下:void Union(int root1, int root2){ int x = FindSet(root1), y = FindSet(root2); if( x == y ) return ; if( ...
阅读全文
摘要:使用并查集查找时,如果查找次数很多,那么使用朴素版的查找方式肯定要超时。比如,有一百万个元素,每次都从第一百万个开始找,这样一次运算就是10^6,如果程序要求查找个一千万次,这样下来就是10^13,肯定要出问题的。 这是朴素查找的代码,适合数据量不大的情况:int findx(int x){ int r=x; while(parent[r] !=r) r=parent[r]; return r;} 下面是采用路径压缩的方法查找元素:int find(int x) //查找x元素所在的集合,回溯时压缩路径{ if (x != parent[x]) { parent[x] = find(pare.
阅读全文

浙公网安备 33010602011771号