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算完之后对每个询问再暴力路径上的每个点放进vector排序输出第k大..
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
#include <cmath>
#include <map>
#include <vector>
using namespace std;
#define N 80010
#define M 30010
struct node
{
int u, v, next;
}edge[N*];
struct P
{
int u, v, next, num, k, lca;
}Edge[M*];
int n, m, tot, Tot, head[N], Head[N], a[N], fa[N], dis[N];
bool vis[N];
vector<int> vec; void init()
{
tot = Tot = ;
memset(head, -, sizeof(head));
memset(Head, -, sizeof(Head));
memset(dis, -, sizeof(dis));
memset(vis, false, sizeof(vis));
for(int i = ; i <= n; i++) fa[i] = i;
} void add(int u, int v)
{
edge[tot].u = u; edge[tot].v = v; edge[tot].next = head[u]; head[u] = tot++;
} void Add(int u, int v, int k)
{
Edge[Tot].k = k; Edge[Tot].u = u; Edge[Tot].v = v; Edge[Tot].next = Head[u]; Edge[Tot].num = ; Edge[Tot].lca = -; Head[u] = Tot++;
} int Find(int x)
{
while(x != fa[x]) x = fa[x];
return x;
} void Merge(int u, int v)
{
u = Find(u), v = Find(v);
fa[v] = u;
} void tarjan(int u)
{
vis[u] = true;
for(int i = head[u]; ~i; i = edge[i].next) {
int v = edge[i].v;
if(!vis[v]) {
dis[v] = dis[u] + ;
tarjan(v);
fa[v] = u;
}
}
for(int i = Head[u]; ~i; i = Edge[i].next) {
int v = Edge[i].v, k = Edge[i].k;
if(vis[v]) {
int ff = Find(v);
if(k) {
Edge[i].num = Edge[i^].num = dis[u] + dis[v] - * dis[ff];
Edge[i].lca = Edge[i^].lca = ff;
}
else a[u] = v;
}
}
} int doit(int u, int v, int k, int num, int lca)
{
vec.clear();
while(u != lca) {
vec.push_back(a[u]); u = fa[u];
}
while(v != lca) {
vec.push_back(a[v]); v = fa[v];
}
vec.push_back(a[lca]);
sort(vec.begin(), vec.end());
num++;
return vec[num-k];
} void solve()
{
for(int i = ; i < Tot; i += ) {
int u = Edge[i].u, v = Edge[i].v, k = Edge[i].k, num = Edge[i].num, lca = Edge[i].lca;
if(k) {
if(num + < k) puts("invalid request!");
else printf("%d\n", doit(u, v, k, num, lca));
}
}
} int main()
{
scanf("%d%d", &n, &m);
init();
for(int i = ; i <= n; i++) scanf("%d", a+i);
for(int i = ; i < n; i++) {
int u, v;
scanf("%d%d", &u, &v);
add(u, v); add(v, u);
}
for(int i = ; i < m; i++) {
int u, v, k;
scanf("%d%d%d", &k, &u, &v);
Add(u, v, k); Add(v, u, k);
}
dis[] = ;
tarjan();
solve();
return ;
}
HDU 3078:Network(LCA之tarjan)的更多相关文章
- HDU 3078 Network(LCA dfs)
Network [题目链接]Network [题目类型]LCA dfs &题意: 给出n个点的权值,m条边,2种操作 0 u num,将第u个点的权值改成num k u v,询问u到v这条路上 ...
- HDU 3078 Network LCA
题意:n个点 m个询问,下面一行是n 个点的权值 再下面n-1行是双向的边 然后m个询问:k u v 若k==0,则把u点的权值改为v,否则回答u->v之间最短路经过点的权值中 第k大的值是多 ...
- hdu 3078 Network (暴力)+【LCA】
<题目链接> 题目大意:给定一颗带点权的树,进行两种操作,k=0,更改某一点的点权,k!=0,输出a~b路径之间权值第k大的点的点权. 解题分析:先通过RMQ的初始化,预处理pre[]数组 ...
- HDU - 3078 Network(暴力+LCA)
题目大意:给出n个点的权值.m条边,2种操作 0 u num,将第u个点的权值改成num k u v,询问u到v这条路上第k大的权值点 解题思路:该点的话直接该,找第k大的话直接暴力 #include ...
- HDU 2460 Network 傻逼Tarjan
Network Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- HDU 3078 Network
简单的 RMQ: 先预处理得到 所有 节点的 公共祖先 和 dfs 得到所有节点的父亲节点: 然后 询问时,从自己出发向上找父亲, 然后 得到所有的节点:排序一下 不知道 这题这样也 ...
- HDU 2460 Network(双连通+树链剖分+线段树)
HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...
- luogu3379 【模板】最近公共祖先(LCA) Tarjan
LCA的Tarjan算法是一个离线算法,复杂度$O(n+q)$. 我们知道Dfs搜索树时会形成一个搜索栈.搜索栈顶节点cur时,对于另外一个节点v,它们的LCA便是v到根节点的路径与搜索栈开始分叉的那 ...
- LCA (Tarjan&倍增)
LCA_Tarjan 参考博客:https://www.cnblogs.com/JVxie/p/4854719.html LCA的Tarjan写法需要结合并查集 从叶子节点往上并 int Find ( ...
随机推荐
- C#开发ActiveX插件-aspx中嵌入
刚到新的公司,第一周让我熟悉一下他们用的silverlight和arcgis.这周,也就是昨天分配了我一个小小的任务! 哪个项目的不知道,是让我实现一个在aspx中嵌入activeX插件! 在网上找了 ...
- javascript实例学习之三——类新浪微博的登录框
该登录框和百度的搜索框类似,可以实现如下效果: 1.文字输入时自动弹出提示层 2,提示层根据输入文字进行自动过滤 3,提示层可以使用上下按键进行选择 4,提示层可以点击或者回车来确认输入 微博登录框h ...
- 安装GRID时跑root.sh脚本报错(ORA-27091: unable to queue I/O)
在安装GRID过程中,运行root.sh脚本时报如下信息: Adding Clusterware entries to upstart CRS-2672: Attempting to start 'o ...
- iOS-self.layer.shouldRasterize属性
当shouldRasterize设成true时,layer被渲染成一个bitmap,并缓存起来,等下次使用时不会再重新去渲染了.实现圆角本身就是在做颜色混合(blending),如果每次页面出来时都b ...
- Android根据baidu Android定位SDK实现定位
参考: http://www.open-open.com/lib/view/open1346982366162.html http://api.map.baidu.com/lbsapi/cloud/g ...
- 解决多线程调用sql存储过程问题
场景: 我们程序现在改成多线程了,我现在需要把临时表中的数据给插入到TABLE_M中,但这时候可能其他的线程也在插入,我就不能用之前我们的方案了(select max(oid) from Tuning ...
- PostgreSQL Replication之第十二章 与Postgres-XC一起工作(5)
12.5 创建表和发送查询 介绍了Postgres-XC以及其底层的思想之后,是时候创建我们的第一个表,看看集群将如何表现.下面的例子演示了一个简单的表.将使用id列的哈希键来分布它: test=# ...
- 很赞的PHP字符串加密函数
最近, 从discuz里面发现了一个很牛的加密解密函数. 此函数的厉害之处在于可以在指定时间内加密还原字符串,超时无法还原 这样我们就可以拿此函数来做很多用途了,比如:单点登录的token加密传输啦, ...
- int 与 Integer--话说数组转集合
话说是自从JDK5后,而这就可以自动进行类型转换了. 当然,区别还是有的,就是对象和“非对象”什么的.可是,今天进行一个测试,出了一个小问题,现将代码贴下: 代码0:先来一个正常点的,用String进 ...
- sql 表连接 join
inner join 和 join 的 区别 inner join 是内连接 ,查询出两边 都有的数据 join 是交叉 连接, 假设集合A={a, b},集合B={0, 1, 2},则两个集 ...