hdu 3078 Network lca

题目链接

给一棵树, m个操作, 一共两种操作, 将第x个点的权值改为y, 询问x->y路径上权值第k大的点的权值。

暴力的找.....

  1 #include <iostream>
  2 #include <vector>
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <algorithm>
  6 #include <cmath>
  7 #include <map>
  8 #include <set>
  9 #include <string>
 10 #include <queue>
 11 #include <stack>
 12 #include <bitset>
 13 using namespace std;
 14 #define pb(x) push_back(x)
 15 #define ll long long
 16 #define mk(x, y) make_pair(x, y)
 17 #define lson l, m, rt<<1
 18 #define mem(a) memset(a, 0, sizeof(a))
 19 #define rson m+1, r, rt<<1|1
 20 #define mem1(a) memset(a, -1, sizeof(a))
 21 #define mem2(a) memset(a, 0x3f, sizeof(a))
 22 #define rep(i, n, a) for(int i = a; i<n; i++)
 23 #define fi first
 24 #define se second
 25 typedef pair<int, int> pll;
 26 const double PI = acos(-1.0);
 27 const double eps = 1e-8;
 28 const int mod = 1e9+7;
 29 const int inf = 1061109567;
 30 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
 31 const int maxn = 1e5+5;
 32 int head[maxn*2], num, f[maxn], deep[maxn], n, val[maxn];
 33 struct node
 34 {
 35     int to, nextt;
 36 }e[maxn*2];
 37 void add(int u, int v) {
 38     e[num].to = v, e[num].nextt = head[u], head[u] = num++;
 39 }
 40 void init() {
 41     num = 0;
 42     mem1(head);
 43 }
 44 void dfs(int u, int fa) {
 45     f[u] = fa;
 46     for(int i = head[u]; ~i; i = e[i].nextt) {
 47         int v = e[i].to;
 48         if(v == fa)
 49             continue;
 50         deep[v] = deep[u]+1;
 51         dfs(v, u);
 52     }
 53 }
 54 int lca(int k, int a, int b)
 55 {
 56     int i,j;
 57     vector <int> v;
 58     if(deep[a]<deep[b])
 59         swap(a, b);
 60     while(deep[a]>deep[b]) {
 61         v.pb(val[a]);
 62         a = f[a];
 63     }
 64     while(a!=b) {
 65         v.pb(val[a]);
 66         v.pb(val[b]);
 67         a = f[a];
 68         b = f[b];
 69     }
 70     v.pb(val[a]);
 71     if(k>v.size())
 72         return -1;
 73     sort(v.begin(), v.end());
 74     reverse(v.begin(), v.end());
 75     return v[k-1];
 76 }
 77 int main()
 78 {
 79     int x, y, m, w, z, sign;
 80     while(cin>>n>>m) {
 81         init();
 82         for(int i = 1; i<=n; i++)
 83             scanf("%d", &val[i]);
 84         for(int i = 0; i<n-1; i++) {
 85             scanf("%d%d", &x, &y);
 86             add(x, y);
 87             add(y, x);
 88         }
 89         dfs(1, 0);
 90         while(m--) {
 91             scanf("%d%d%d", &sign, &x, &y);
 92             if(!sign) {
 93                 val[x] = y;
 94             } else {
 95                 int ans = lca(sign, x, y);
 96                 if(~ans)
 97                     cout<<ans<<endl;
 98                 else
 99                     puts("invalid request!");
100             }
101         }
102     }
103     return 0;
104 }
时间: 2024-10-17 17:37:16

hdu 3078 Network lca的相关文章

HDU 3078 Network LCA水题

Problem Description The ALPC company is now working on his own network system, which is connecting all N ALPC department. To economize on spending, the backbone network has only one router for each department, and N-1 optical fiber in total to connec

HDU - 3078 Network(暴力+LCA)

题目大意:给出n个点的权值,m条边,2种操作 0 u num,将第u个点的权值改成num k u v,询问u到v这条路上第k大的权值点 解题思路:该点的话直接该,找第k大的话直接暴力 #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define N 80010 #define M 160010 struct Edge{ int to, next, val; }

HDU 3078 Network

Network Problem Description The ALPC company is now working on his own network system, which is connecting all N ALPC department. To economize on spending, the backbone network has only one router for each department, and N-1 optical fiber in total t

HDU 2460 Network(双连通+树链剖分+线段树)

HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链剖分+线段树处理 代码: #include <cstdio> #include <cstring> #include <algorithm> #include <vector> using namespace std; #pragma comment(linke

HDU 3078:Network(LCA之tarjan)

http://acm.hdu.edu.cn/showproblem.php?pid=3078 题意:给出n个点n-1条边m个询问,每个点有个权值,询问中有k,u,v,当k = 0的情况是将u的权值修改成v,当k不为0的情况是问u和v的路径中权值第k大的点的权值是多少. 思路:比较暴力的方法,可能数据太水勉强混过去了.对于每一个询问的时候保留两个点之间的lca,还有计算出两个点之间的点的个数(询问的时候如果点的个数小于k就不用算了),然后tarjan算完之后对每个询问再暴力路径上的每个点放进vec

HDU 3078 (LCA+树链第K大)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3078 题目大意:定点修改.查询树中任意一条树链上,第K大值. 解题思路: 先用离线Tarjan把每个Query树链的LCA求出来. LCA中对连接树Dfs的时候,令p[v]=u,记录v的前驱. LCA结束后,对于每个Query: 从u开始回溯到LCA,记录值.从v开始回溯到LCA,记录值. 再加上LCA这个点的值,形成一条完整树链.特判树链长度是否小于K. 对树链中的值,从大到小排序,取第K大即可

hdu 3078(LCA的在线算法)

Network Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 847    Accepted Submission(s): 347 Problem Description The ALPC company is now working on his own network system, which is connecting all

HDU 2460 Network(桥+LCA)

http://acm.hdu.edu.cn/showproblem.php?pid=2460 题意:给出图,求每次增加一条边后图中桥的数量. 思路: 先用tarjan算法找出图中所有的桥,如果lowv>pre[u],那么u—v就是桥,此时可以标记一下v. 之后就是利用LCA,找到两个节点的公共祖先,在这条路径上的桥就不再是桥了.(此时就相当于这些桥组成的树,可以在脑海中缩点) 1 #include<iostream> 2 #include<algorithm> 3 #incl

HDU - 2460 Network(桥+LCA)

题目大意:给出一张图,现在要往这张图上加边,问加完边后,这张图还有多少条桥 解题思路:求出连通分量,压缩成点,用桥连接,形成了棵树 每次添加边时,就找一下是否在同一个强连通分量内,如果在同一个强连通分量内,那么桥的数量不变 反之,求出两个点的LCA,并且把LCA到这两个点的桥全部去掉(因为加边后,形成了环,构成了一个新的强连通分量了) #include <cstdio> #include <cstring> using namespace std; #pragma comment(