日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HDU 6203 ping ping ping LCA + 贪心

發布時間:2024/3/26 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HDU 6203 ping ping ping LCA + 贪心 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

有一個\(N+1\)個結點的樹\(T\)
現在有\(Q\)個信息,每條信息為\(q:(u,v)\),表示\(u\)\(v\)的路徑不通。
問樹\(T\)至少被破壞多少個節點才能達到當前這種局面。

#include <bits/stdc++.h> #define DBG(x) cerr << #x << " = " << x << endlusing namespace std; typedef long long LL;#define mt(a, b) memset(a, b, sizeof(a))struct LCA { ///最近公共祖先 build O(V*logV) query O(1)typedef int typec; ///邊權的類型static const int MV = 100000 + 16; ///點的個數static const int MR = MV << 1; ///rmq 的個數int Index, H[MV], dex[MR], a[MR], b[MR], F[MR], ra[MR][20], rb[MR][20];typec dist[MV];struct G {struct E {int v, next;typec w;} e[MV << 1];int le, head[MV];void init(int n) {le = 0;for(int i = 0; i <= n; i++) head[i] = -1;}void add(int u, int v, typec w) {e[le].v = v;e[le].w = w;e[le].next = head[u];head[u] = le++;}} g;void init_dex() {dex[0] = -1;for(int i = 1; i < MR; i++) {dex[i] = dex[i >> 1] + 1;}}void dfs(int u, int fa, int level) {a[Index] = u;b[Index++] = level;F[u] = fa;for(int i = g.head[u]; ~i; i = g.e[i].next) {int v = g.e[i].v;if(v == fa) continue;dist[v] = dist[u] + g.e[i].w;dfs(v, u, level + 1);a[Index] = u;b[Index++] = level;}}LCA() {init_dex();};void init(int n) {g.init(n);}void add(int u, int v, typec w) {g.add(u, v, w);g.add(v, u, w);}void build(int root) { ///傳入樹根Index = 0;dist[root] = 0;dfs(root, -1, 0);mt(H, -1);mt(rb, 0x3f);for(int i = 0; i < Index; i++) {int tmp = a[i];if(H[tmp] == -1) H[tmp] = i;rb[i][0] = b[i];ra[i][0] = a[i];}for(int i = 1; (1 << i) <= Index; i++) {for(int j = 0; j + (1 << i) < Index; j++) {int next = j + (1 << (i - 1));if(rb[j][i - 1] <= rb[next][i - 1]) {rb[j][i] = rb[j][i - 1];ra[j][i] = ra[j][i - 1];continue;}rb[j][i] = rb[next][i - 1];ra[j][i] = ra[next][i - 1];}}}int getlca(int l, int r) { ///查最近公共祖先l = H[l];r = H[r];if(l > r) swap(l, r);int p = dex[r - l + 1];r -= (1 << p) - 1;return rb[l][p] <= rb[r][p] ? ra[l][p] : ra[r][p];}typec getdist(int id) { ///查根到點最短距離return dist[id];}typec getdist(int l, int r) { ///查兩點最短距離return dist[l] + dist[r] - 2 * dist[getlca(l, r)];} } yoshiko;int n, q;struct Query {int u, v, lca, d;Query(int u, int v, int lca, int d): u(u), v(v), lca(lca), d(d) {}Query() {}bool operator < (const Query &rhs) const {return d > rhs.d;} };bool vis[100000 + 16];void dfs(int u) {vis[u] = true;for(int i = yoshiko.g.head[u]; ~i; i = yoshiko.g.e[i].next) {int v = yoshiko.g.e[i].v;if(v != yoshiko.F[u] && !vis[v]) dfs(v);} }int main(int argc, char **argv) {while(~scanf("%d", &n)) {++n; yoshiko.init(n);for(int i = 1; i < n; ++i) {int u, v; scanf("%d%d", &u, &v);yoshiko.add(u, v, 1);}yoshiko.build(0);vector<Query> Q;scanf("%d", &q);while(q--) {int u, v; scanf("%d%d", &u, &v);int lca = yoshiko.getlca(u, v);int dist = yoshiko.getdist(lca);Q.push_back(Query(u, v, lca, dist));}sort(Q.begin(), Q.end());int ans = 0;memset(vis, false, sizeof(vis));for(auto &query : Q) {if(!vis[query.u] && !vis[query.v]) {++ans;dfs(query.lca);}}printf("%d\n", ans);}return 0; }

轉載于:https://www.cnblogs.com/ToRapture/p/7552780.html

總結

以上是生活随笔為你收集整理的HDU 6203 ping ping ping LCA + 贪心的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。