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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

图论--LCA--Tarjan(离线)

發布時間:2023/12/15 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 图论--LCA--Tarjan(离线) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
** 給出一顆有向樹,Q個查詢* 輸出查詢結果中每個點出現次數* 復雜度O(n + Q);*/ const int MAXN = 1010; const int MAXQ = 500010; // 查詢數的最大值// 并查集部分 int F[MAXN]; // 需要初始化為-1int find(int x) {if (F[x] == -1){return x;}return F[x] = find(F[x]); }void bing(int u, int v) {int t1 = find(u);int t2 = find(v);if (t1 != t2){F[t1] = t2;} }bool vis[MAXN]; // 訪問標記 int ancestor[MAXN]; // 祖先 struct Edge {int to, next; } edge[MAXN * 2]; int head[MAXN],tot;void addedge(int u, int v) {edge[tot].to = v;edge[tot].next = head[u];head[u] = tot++; }struct Query {int q, next;int index; // 查詢編號 } query[MAXQ * 2];int answer[MAXQ]; // 存儲最后的查詢結果,下標0~Q-1 int h[MAXQ]; int tt; int Q;void add_query(int u, int v, int index) {query[tt].q = v;query[tt].next = h[u];query[tt].index = index;h[u] = tt++;query[tt].q = u;query[tt].next = h[v];query[tt].index = index;h[v] = tt++; }void init() {tot = 0;memset(head, -1, sizeof(head));tt = 0;memset(h, -1, sizeof(h));memset(vis, false, sizeof(vis));memset(F, -1, sizeof(F));memset(ancestor, 0, sizeof(ancestor)); }void LCA(int u) {ancestor[u] = u;vis[u] = true;for (int i = head[u]; i != -1; i = edge[i].next){int v = edge[i].to;if (vis[v]){continue;}LCA(v);bing(u, v);ancestor[find(u)] = u;}for (int i = h[u]; i != -1; i = query[i].next){int v = query[i].q;if (vis[v]){answer[query[i].index] = ancestor[find(v)];}} }bool flag[MAXN]; int Count_num[MAXN];int main() {int n;int u, v, k;while (scanf("%d", &n) == 1){init();memset(flag, false, sizeof(flag));for (int i = 1; i <= n; i++){scanf("%d:(%d)", &u, &k);while (k--){scanf("%d", &v);flag[v] = true;addedge(u,v);addedge(v,u);}}scanf("%d", &Q);for (int i = 0; i < Q; i++){char ch;cin >> ch;scanf("%d %d)", &u, &v);add_query(u, v, i);}int root;for (int i = 1; i <= n; i++){if (!flag[i]){root = i;break;}}LCA(root);memset(Count_num, 0, sizeof(Count_num));for (int i = 0; i < Q; i++){Count_num[answer[i]]++;}for (int i = 1; i <= n; i++){if (Count_num[i] > 0){printf("%d:%d\n", i, Count_num[i]);}}}return 0; }

?

總結

以上是生活随笔為你收集整理的图论--LCA--Tarjan(离线)的全部內容,希望文章能夠幫你解決所遇到的問題。

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