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

建设一个网站的费用百度6大核心部门

建设一个网站的费用,百度6大核心部门,查询网站这么做,手游网站怎么做的题目描述 小杨有一棵包含 $ n $ 个节点的树,其中节点的编号从 1 到 $ n $。 小杨设置了一个好点对 { ⟨ u 1 , v 1 ⟩ , ⟨ u 2 , v 2 ⟩ , … , ⟨ u a , v a ⟩ } \{\langle u_1, v_1 \rangle, \langle u_2, v_2 \rangle, \dots, \langle u_a, v_a \rangle\} {…

题目描述

小杨有一棵包含 $ n $ 个节点的树,其中节点的编号从 1 到 $ n $。

小杨设置了一个好点对 { ⟨ u 1 , v 1 ⟩ , ⟨ u 2 , v 2 ⟩ , … , ⟨ u a , v a ⟩ } \{\langle u_1, v_1 \rangle, \langle u_2, v_2 \rangle, \dots, \langle u_a, v_a \rangle\} {⟨u1,v1,u2,v2,,ua,va⟩} 和一个坏点对 ⟨ b u , b v ⟩ \langle b_u, b_v \rangle bu,bv。一个节点能被删除,当且仅当:

  • 删除该节点后对于所有的 $ 1 \leq i \leq a $,好点对 $ u_i $ 和 $ v_i $ 仍然连通;
  • 删除该节点后坏点对 $ b_u $ 和 $ b_v $ 不连通。

如果点对中的任意一个节点被删除,其视为不连通。

小杨想知道,还有多少个节点能被删除。

输入格式

第一行包含两个非负整数 $ n $, $ a $,含义如下题面所示。

接下来 n − 1 n - 1 n1 行,每行包含两个正整数 $ x_i, y_i $,代表存在一条连接节点 $ x_i $ 和 $ y_i $ 的边;

之后 $ a $ 行,每行包含两个正整数 $ u_i, v_i $,代表一个好点对 $ \langle u_i, v_i \rangle $;

最后一行包含两个正整数 $ b_u, b_v $,代表坏点对 $ \langle b_u, b_v \rangle $。

输出格式

输出一个非负整数,代表删除的节点个数。

输入输出样例 #1

输入 #1

6 2
1 3
1 5
3 6
3 2
5 4
5 4
5 3
2 6

输出 #1

2

说明/提示

子任务编号分值$ n $$ a $
1 20 20 20 = 10 =10 =10 = 0 =0 =0
2 20 20 20$ \leq 100 $$ \leq 100 $
3 60 60 60$ \leq 10^6 $$ \leq 10^5 $

对于全部数据,保证有 $ 1 \leq n \leq 10^6 $, $ 0 \leq a \leq 10^5 $, $ u_i \neq v_i $, $ b_u \neq b_v $。

solution

如果 u ,v 的路径上的一点被删除,则 u, v 不联通,所以被删除的点应该满足两个条件

  • 在坏点对点路径上
  • 不在任何好点对的路径上
    所以可以遍历坏点对路径上的每一点,如果它不在任何好点对上则满足条件。可以结合最近公共祖先完成判断。

代码

#include <iostream>
#include "bit"
#include "vector"
#include "unordered_set"
#include "unordered_map"
#include "set"
#include "queue"
#include "algorithm"
#include "bitset"
#include "cstring"
#include "cmath"using namespace std;const int N = 1e6 + 1, M = 1e5 + 1;
int n, a, U[M], V[M], s, t, f[N][21], d[N];
vector<int> e[N];void dfs(int u, int p) {d[u] = d[p] + 1;f[u][0] = p;for (int i = 1; i <= 20; i++) f[u][i] = f[f[u][i - 1]][i - 1];for (int v: e[u]) {if (v != p) {dfs(v, u);}}
}int lca(int x, int y) {if (x == y) return x;if (d[x] < d[y]) swap(x, y);for (int i = 20; d[x] > d[y]; i--) {if (d[f[x][i]] >= d[y])x = f[x][i];}if (x == y) return x;for (int i = 20; i >= 0; i--) {if (f[x][i] != f[y][i])x = f[x][i], y = f[y][i];}return f[x][0];
}int main() {scanf("%d %d", &n, &a);for (int i = 1; i < n; i++) {int x, y;scanf("%d %d", &x, &y);e[x].push_back(y);e[y].push_back(x);}for (int i = 1; i <= a; i++) scanf("%d %d", &U[i], &V[i]);scanf("%d %d", &s, &t);dfs(1, 0);int p = lca(s, t);int cnt = 0;for (; s != p; s = f[s][0]) {int tt = 1;for(int i = 1; i <= a; i++){int P =  lca(U[i], V[i]);if(lca(P, s) == P && (lca(s, U[i]) == s || lca(s, V[i]) == s)){tt = 0;break;}}cnt += tt;}for (; ; t = f[t][0]) {int tt = 1;for(int i = 1; i <= a; i++){int P =  lca(U[i], V[i]);if(lca(P, t) == P && (lca(t, U[i]) == t || lca(t, V[i]) == t)){tt = 0;break;}}cnt += tt;if(t == p) break;}cout << cnt;
}
  • 用 dfn 序求最近公共祖先,可以将对数级别降低到常数级别。
#include <iostream>
#include "bit"
#include "vector"
#include "unordered_set"
#include "unordered_map"
#include "set"
#include "queue"
#include "algorithm"
#include "bitset"
#include "cstring"
#include "cmath"using namespace std;const int N = 1e6 + 1, M = 1e5 + 1;
int n, a, U[M], V[M], s, t, f[N][21], id, dfn[N];
vector<int> e[N];void dfs(int u, int p) {f[dfn[u] = ++id][0] = p;for (int v: e[u]) {if (v != p) {dfs(v, u);}}
}inline int my_min(int x, int y){return dfn[x] < dfn[y] ? x : y;
}int lca(int x, int y) {if (x == y) return x;x = dfn[x], y = dfn[y];if (x > y) swap(x, y);int d = (int)log2(y - x);x++;// 求 x y 之间 dfn 最小的那个数return my_min(f[x][d], f[y - (1 << d) + 1][d]);
}int main() {scanf("%d %d", &n, &a);for (int i = 1; i < n; i++) {int x, y;scanf("%d %d", &x, &y);e[x].push_back(y);e[y].push_back(x);}for (int i = 1; i <= a; i++) scanf("%d %d", &U[i], &V[i]);scanf("%d %d", &s, &t);dfs(1, 0);for (int j = 1; j < log2(n) + 1; j++) {for (int i = 1; i + (1 << (j - 1)) <= n; i++) {f[i][j] = my_min(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);}}int p = lca(s, t);int cnt = 0;for (; s != p; s = f[dfn[s]][0]) {int tt = 1;for (int i = 1; i <= a; i++) {int P = lca(U[i], V[i]);if (lca(P, s) == P && (lca(s, U[i]) == s || lca(s, V[i]) == s)) {tt = 0;break;}}cnt += tt;}for (;; t = f[dfn[t]][0]) {int tt = 1;for (int i = 1; i <= a; i++) {int P = lca(U[i], V[i]);if (lca(P, t) == P && (lca(t, U[i]) == t || lca(t, V[i]) == t)) {tt = 0;break;}}cnt += tt;if (t == p) break;}cout << cnt;}
  • 由于输入数据量达到百万级别,改用 getchar 快速读入可以节约时间
#include <iostream>
#include "bit"
#include "vector"
#include "unordered_set"
#include "unordered_map"
#include "set"
#include "queue"
#include "algorithm"
#include "bitset"
#include "cstring"
#include "cmath"using namespace std;const int N = 1e6 + 1, M = 1e5 + 1;
int n, a, U[M], V[M], s, t, f[N][21], id, dfn[N];
vector<int> e[N];void dfs(int u, int p) {f[dfn[u] = ++id][0] = p;for (int v: e[u]) {if (v != p) {dfs(v, u);}}
}inline int read() {int s = 0, w = 1;int ch = getchar();while (ch < '0' || ch > '9') { if (ch == '-') w = -1; ch = getchar(); }while (ch >= '0' && ch <= '9') { s = s * 10 + ch - '0'; ch = getchar();}return s * w;
}inline int my_min(int x, int y){return dfn[x] < dfn[y] ? x : y;
}int lca(int x, int y) {if (x == y) return x;x = dfn[x], y = dfn[y];if (x > y) swap(x, y);int d = (int)log2(y - x);x++;// 求 x y 之间 dfn 最小的那个数return my_min(f[x][d], f[y - (1 << d) + 1][d]);
}int main() {n = read(), a = read();for (int i = 1; i < n; i++) {int x, y;x = read(), y = read();e[x].push_back(y);e[y].push_back(x);}for (int i = 1; i <= a; i++) U[i] = read(), V[i] = read();//scanf("%d %d", &U[i], &V[i]);s = read(), t = read();dfs(1, 0);for (int j = 1; j < log2(n) + 1; j++) {for (int i = 1; i + (1 << (j - 1)) <= n; i++) {f[i][j] = my_min(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);}}int p = lca(s, t);int cnt = 0;for (; s != p; s = f[dfn[s]][0]) {int tt = 1;for (int i = 1; i <= a; i++) {int P = lca(U[i], V[i]);if (lca(P, s) == P && (lca(s, U[i]) == s || lca(s, V[i]) == s)) {tt = 0;break;}}cnt += tt;}for (;; t = f[dfn[t]][0]) {int tt = 1;for (int i = 1; i <= a; i++) {int P = lca(U[i], V[i]);if (lca(P, t) == P && (lca(t, U[i]) == t || lca(t, V[i]) == t)) {tt = 0;break;}}cnt += tt;if (t == p) break;}cout << cnt;
}

结果

用树上倍增求最近公共祖先的时间
在这里插入图片描述
用 dfn 序列求最近公共祖先的时间
在这里插入图片描述
改用快速读入时通过的时间
在这里插入图片描述

小结

这高低复杂度用树上差分好像复杂度更优一点

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

相关文章:

  • 网站底版照片怎么做seo外链是什么
  • 美国做色情网站犯法吗seo网站优化培训公司
  • iis 设置网站权限网站推广方法有哪些
  • 机械类 网站源码公司网站制作教程
  • 织梦pc怎么做手机网站东莞关键词优化平台
  • 关于重新建设网站的申请seo培训一对一
  • 阿拉丁做网站怎么做的在线培训平台
  • 如何使用模板网站建设网页正规推广赚佣金的平台
  • 长沙品牌网站建设河池网站seo
  • 工程建设监理学校网站网站推广四个阶段
  • 微网站建设的第一步是进行首页的设置一点优化
  • wordpress英文字体样式麒麟seo软件
  • 企业自助网站建设南京最大网站建设公司
  • 可以做网站吗何鹏seo
  • 怎么在百度做公司网站哪家建设公司网站
  • 店面转让找哪个网站做搜索引擎优化人员优化
  • 免费做网站的问题做个网页价格多少
  • 大连里程科技做网站谷歌seo怎么优化
  • php ajax网站开发典型实例网站制作免费
  • 政府找网站开发商要求百度推广首页
  • 英文集团网站设计建设网络广告文案案例
  • 农村自建房设计图120平方米三层百度关键词自然排名优化公司
  • 网上做网站兼职陕西网络营销优化公司
  • 网站开发网页超链接路径泉州百度广告
  • 哪个网站做系统好杭州网站建设公司
  • 淘宝客网站开发教程免费域名注册二级域名
  • 政府网站建设 政府采购十大接单推广app平台
  • 源码网棋牌海城seo网站排名优化推广
  • 网页设计师培训费用上海seo公司
  • 动态网站建设简介北京百度seo服务