【图论05】并查集 1005 More is better
2013-06-28 20:40
441 查看
开始用普通的并查集,一直TLE,后来看到大牛的代码,领悟到可以在findset函数被执行的过程中进一步压缩路径,这样的话下次如果执行findset时同样的路径会快很多,因为上次走同样路劲的时候已经把“长链”拉直了。
还有大牛说需要离散化,能够达到优化,这里没有采用。
还有大牛说需要离散化,能够达到优化,这里没有采用。
//模板开始 #include <string> #include <vector> #include <algorithm> #include <iostream> #include <sstream> #include <fstream> #include <map> #include <set> #include <cstdio> #include <cmath> #include <cstdlib> #include <ctime> #include<iomanip> #include<string.h> #define SZ(x) (int(x.size())) using namespace std; int toInt(string s){ istringstream sin(s); int t; sin>>t; return t; } template<class T> string toString(T x){ ostringstream sout; sout<<x; return sout.str(); } typedef long long int64; int64 toInt64(string s){ istringstream sin(s); int64 t; sin>>t; return t; } template<class T> T gcd(T a, T b){ if(a<0) return gcd(-a, b); if(b<0) return gcd(a, -b); return (b == 0)? a : gcd(b, a % b); } //模板结束(通用部分) #define ifs cin #define MAX_SIZE 10000005 int next_node[MAX_SIZE]; //存储边 //int in[MAX_SIZE]; //存储节点的入度 //int out[MAX_SIZE]; //存储节点的出度 //int flag[MAX_SIZE]; //标记节点是否存在 int tongji[MAX_SIZE]; //以下标对应结点为代表元的集合的元素个数统计(实际上只是更新了新的代表元的信息,最后可以通过遍历得到其中值个数最大的一个) int max_tongji; //void init() //初始化 //{ // for(int i = 0; i < MAX_SIZE; i++) // { // next_node[i] = i; // } // //memset(in, 0, sizeof(in)); // //memset(out, 0, sizeof(out)); // memset(flag, 0, sizeof(flag)); //} void init_advance() //初始化 { for(int i = 0; i < MAX_SIZE; i++) { next_node[i] = i; } //memset(in, 0, sizeof(in)); //memset(out, 0, sizeof(out)); //memset(flag, 0, sizeof(flag)); for(int i = 0; i < MAX_SIZE; i++) { tongji[i] = 1; } max_tongji = 1; } int findset(int v) //找元素所在集合的代表元(因为用了路径压缩,路径压缩的主要目的是为了尽快的确定元素所在的集合) { int t1,t2=v; while(v!=next_node[v]) v=next_node[v]; while(t2!=next_node[t2]) //这里优化的思路还是路径压缩(进一步的在查找函数执行的过程中压缩路径),很神奇! { t1=next_node[t2]; next_node[t2]=v; t2=t1; } return v; } //void union_nodes(int a, int b) //集合合并 //{ // int a1 = findset(a); // int b1 = findset(b); // next_node[a1] = b1; //} void union_nodes_advance(int a, int b) //集合合并 { int a1 = findset(a); int b1 = findset(b); if(a1 != b1) { tongji[b1] += tongji[a1]; if(tongji[b1] > max_tongji) { max_tongji = tongji[b1]; } } next_node[a1] = b1; } //【图论05】并查集 1005 More is better int main() { //ifstream ifs("shuju.txt", ios::in); int m, n; int cases; while(~scanf("%d", &cases)) { init_advance(); for(int i = 0; i < cases; i++) { scanf("%d%d", &m, &n); union_nodes_advance(m, n); //flag[m]++; //flag ++; } //int max_tongji = tongji[0]; //for(int i = 1; i < MAX_SIZE; i++) //{ // if(tongji[i] > max_tongji) // { // max_tongji = tongji[i]; // } //} printf("%d\n", max_tongji); } return 0; }
相关文章推荐
- 图论基础之并查集的简单看法:HDU 1232 畅通工程&&More is better
- 并查集-杭电1856-More is better-难度1
- hdoj 1856 More is better 【并查集 求最大节点数】
- hdu 1856 More is better(数据结构:并查集)
- HDU 1856 More is better (并查集)
- HDU 1856 More is better (并查集)
- HDU1865--More is better(统计并查集的秩(元素个数))
- HDUOJ----More is better(并查集)
- hdu 1856 More is better(并查集)
- 【HDU1856】More is better(并查集)
- (并查集)More is better--HDOJ
- more is better(并查集)
- HDU 1856 More is better(基础并查集)
- hdu 1988-More is better-带权并查集
- HDU 1856 More is better (并查集)
- HDU 1856 More is better(并查集)
- HDU 1856 More is better (并查集基本操作)
- 并查集——More is better
- More is better---hdu1856(并查集)
- HDU1856 More is better(并查集)