当前位置: 首页 > wzjs >正文

交互型网站开发沈阳seo排名优化推广

交互型网站开发,沈阳seo排名优化推广,网页制作个人简历代码,在郑州网站推广一、理论基础 (1)并查集的功能及实现原理 首先要知道并查集可以解决什么问题呢? 当我们需要判断两个元素是否在同一个集合里的时候,我们就要想到用并查集。 并查集主要有两个功能: 将两个元素添加到一个集合中。判断…

一、理论基础

(1)并查集的功能及实现原理

首先要知道并查集可以解决什么问题呢?

当我们需要判断两个元素是否在同一个集合里的时候,我们就要想到用并查集。

并查集主要有两个功能:

  • 将两个元素添加到一个集合中。
  • 判断两个元素在不在同一个集合

 如何将两个元素添加到一个集合中?

        将三个元素A,B,C (分别是数字)放在同一个集合,其实就是将三个元素连通在一起,如何连通呢。

        只需要用一个一维数组来表示,即:father[A] = B,father[B] = C 这样就表述 A 与 B 与 C连通了(有向连通图)。

// 将v,u 这条边加入并查集
void join(int u, int v) {u = find(u); // 寻找u的根v = find(v); // 寻找v的根if (u == v) return; // 如果发现根相同,则说明在一个集合,不用两个节点相连直接返回father[v] = u;
}

        find函数是如何实现的呢?其实就是通过数组下标找到数组元素,一层一层寻根过程,代码如下:

// 并查集里寻根的过程
int find(int u) {if (u == father[u]) return u; // 如果根就是自己,直接返回else return find(father[u]); // 如果根不是自己,就根据数组下标一层一层向下找
}

路径压缩:

// 并查集里寻根的过程
int find(int u) {if (u == father[u]) return u;else return father[u] = find(father[u]); // 路径压缩
}

默认自己指向自己,所以

// 并查集初始化
void init() {for (int i = 0; i < n; ++i) {father[i] = i;}
}

如何判断两个元素是否在同一个集合里?

         如果通过 find函数 找到 两个元素属于同一个根的话,那么这两个元素就是同一个集合,代码如下:

// 判断 u 和 v是否找到同一个根
bool isSame(int u, int v) {u = find(u);v = find(v);return u == v;
}

 (2)代码模版

int n = 1005; // n根据题目中节点数量而定,一般比节点数量大一点就好
vector<int> father = vector<int> (n, 0); // C++里的一种数组结构// 并查集初始化
void init() {for (int i = 0; i < n; ++i) {father[i] = i;}
}
// 并查集里寻根的过程
int find(int u) {if (u == father[u]) return u;else return father[u] = find(father[u]); // 路径压缩
}// 判断 u 和 v是否找到同一个根
bool isSame(int u, int v) {u = find(u);v = find(v);return u == v;
}// 将v->u 这条边加入并查集
void join(int u, int v) {u = find(u); // 寻找u的根v = find(v); // 寻找v的根if (u == v) return ; // 如果发现根相同,则说明在一个集合,不用两个节点相连直接返回father[v] = u;
}

通过模板,我们可以知道,并查集主要有三个功能。

  1. 寻找根节点,函数:find(int u),也就是判断这个节点的祖先节点是哪个
  2. 将两个节点接入到同一个集合,函数:join(int u, int v),将两个节点连在同一个根节点上
  3. 判断两个节点是否在同一个集合,函数:isSame(int u, int v),就是判断两个节点是不是同一个根节点

(3)模拟过程

join(3, 8) 在图中为什么 将 元素1 连向元素 3 而不是将 元素 8 连向 元素 3 呢?

        因为join(int u, int v)函数里 要分别对 u 和 v 寻根之后再进行关联。

 

  为什么 图中 8 又直接指向了 3 了呢?

        代码在寻找根的过程中,会有路径压缩的优化        ,减少 下次查询的路径长度。

 

这里为什么是 2 指向了 6,因为 9的根为 2,所以用2指向6。

(4)应用

连通性问题(图论):判断两点是否在同一个连通块、连通块计数

        【把图中每条边两端的点用并查集合并,判断某两个点是否在同一个集合里,就等于判断它们是否在同一个连通块中。查询连通性:判断两个点 ab 是否连通,只需看 find(a) == find(b) 是否成立。】

        【遍历所有节点,统计父节点为自身的节点数量(即根节点数量),即为连通块个数。if (fa[s] == s) landcount++;

最小生成树 

二、基础题练习

(1)排座位

#include <bits/stdc++.h> 
using namespace std;const int N = 110;       // 最大节点数
int fa[N], g[N][N];      // fa数组表示并查集的父节点,g是邻接矩阵记录关系(朋友或敌人)// 并查集的查找函数,带路径压缩
int find(int x) {if (x == fa[x]) return x;           // 如果当前节点是自己的根,返回它自己else return fa[x] = find(fa[x]);    // 否则递归查找,并路径压缩
}// 并查集的合并函数
void merge(int x, int y) {int xx = find(x);   // 找到x的根int yy = find(y);   // 找到y的根if (xx == yy) return; // 如果已经在同一个集合中,不用合并fa[yy] = xx;          // 否则把y的集合合并到x中return;
}int main() {int n, m, k;cin >> n >> m >> k;  // n个点,m条关系,k次查询// 初始化并查集:每个点的父亲是自己for (int i = 1; i < N; i++) fa[i] = i;// 输入m条关系for (int i = 0; i < m; i++) {int x, y, z;cin >> x >> y >> z;g[x][y] = g[y][x] = z; // 建图,g[x][y] = z,z是关系类型(1表示朋友,-1表示敌人)if (z == 1)            // 如果是朋友merge(x, y);      // 用并查集把他们合并为一个集合}// k 次查询while (k--) {int x, y;cin >> x >> y;int xx = find(x), yy = find(y); // 找到两个点所在的集合根if (xx == yy && g[x][y] != -1)       // 如果在一个集合,并且不是敌人cout << "No problem" << endl;else if (xx != yy && g[x][y] != -1)  // 如果不在一个集合,但不是敌人(可能认识但不熟)cout << "OK" << endl;else if (xx == yy && g[x][y] == -1)  // 如果在一个集合但是敌人(朋友里有矛盾)cout << "OK but..." << endl;else                                 // 不在一个集合,又是敌人(八竿子打不着)cout << "No way" << endl;}
}

 (2)部落

#include <bits/stdc++.h>
using namespace std;const int N = 1e4 + 10; // 最大编号范围,保证能容纳所有人
int fa[N];              // 并查集的父亲数组
map<int, bool> st;      // 用于记录输入中出现过的人(防止0~N全部初始化)// 查找函数(带路径压缩)
int find(int x) {if (x == fa[x]) return x;else return fa[x] = find(fa[x]);
}// 合并函数:把x和y所在的集合合并
void merge(int x, int y) {int xx = find(x), yy = find(y);if (xx == yy) return;fa[yy] = xx; // 将y的根指向x的根return;
}int main() {int n;cin >> n;// 初始化:fa[i] = ifor (int i = 0; i < N; i++) fa[i] = i;// 处理输入的朋友圈信息for (int i = 0; i < n; i++) {int k, first_;cin >> k; // 该组朋友圈人数for (int j = 0; j < k; j++) {if (j == 0) {cin >> first_;           // 记录第一个人if (st.count(first_) == 0) st[first_] = 1; // 记录这个人出现了} else {int x;cin >> x;               // 输入其余的人if (st.count(x) == 0) st[x] = 1; // 记录新出现的人merge(x, first_);       // 把当前人和第一个人合并(建朋友圈)}}}// 输出所有出现过的人数cout << st.size() << " ";// 统计朋友圈数量(根节点数量)int num = 0;for (int i = 0; i < N; i++) {if (fa[i] == i && st.count(i) != 0) // 是自己父亲+出现过的人num++;}cout << num << endl;// 查询部分int q;cin >> q;while (q--) {int x, y;cin >> x >> y;if (find(x) == find(y)) cout << "Y" << endl; // 在同一个朋友圈else cout << "N" << endl;                    // 不在一个朋友圈}return 0;
}

http://www.dtcms.com/wzjs/116724.html

相关文章:

  • wordpress分类导航模板宁波seo排名外包
  • 有什么做动画的网站知乎seo优化
  • 如何搭建一个企业子账号网站关键词排名优化技巧
  • 百度做一个网站怎么做呢推手平台哪个靠谱
  • 厦门网站建设要多少钱西安seo关键字优化
  • 网站开发与建设课程个人网站注册平台
  • 专业手机网站开发种子搜索神器网页版
  • 做网站配送地址怎么变换免费有效的推广网站
  • 重庆平台网站建设推荐网站推广费用
  • 苏州最大的网站建设公司b站视频推广网站2023
  • 西安网站建设熊掌号日本比分预测最新分析
  • 定制做网站平台seo成功的案例和分析
  • 完善运营网站建设b站新人视频怎么推广
  • wordpress google font360优化大师官方下载
  • 淮北论坛二手车长沙专业竞价优化首选
  • 查询网站最新域名南昌seo营销
  • 用python做网站的步骤网络推广优化培训
  • 网站维护客户电子商务网站推广
  • 网站怎么做图片转换360优化大师
  • 深圳网站开发培训价格莱阳seo外包
  • 秦皇岛网站建设高端网站建设公司排行
  • 网站可以做充值吗seo上海公司
  • 如何做vip影视网站如何建立独立网站
  • 视频网站策划百度推广管理平台登录
  • 四川网站建设制作seo网站推广是什么意思
  • 官方建网站有哪些步骤网页广告怎么投放
  • 教手工做衣服的网站计算机培训班有用吗
  • 啥是深圳网站建设平台seo什么意思
  • 网站的推广费用票可以做抵扣吗中国企业500强排行榜
  • wordpress 文章选择器seo案例模板