problem

有一个n个点m条边的连通无向图(无重边、无自环),点的编号为1~n。每条边都有一个正的边权,并且每条边边权互不相同(即数据保证该图的最小生成树唯一)。
如果只是求最小生成树,那么Ohyee觉得太简单了,于是他决定考考你。
对于每条边(u,v)都进行询问:
——如果该边在最小生成树上,那么输出“Ohyee”;
——如果该边不在最小生成树上,那么输出最小生成树上u,v两点路径中边权的最小值。

Input

第一行输入两个整数n,m(2<=n<=100000,n-1<=m<=200000)
接下来m行,每行输入三个整数u,v,w。u,v表示该边连接点的编号,w是边权。
(1<=w<=1000000000)

Output

输出一共m行,按照输入的边的顺序回答每条边的询问。

Input

4 4
1 2 2
2 3 5
3 4 7
4 1 3

Output

Ohyee
Ohyee
2
Ohyee

Limitation

1s 256MB

Hint

原图最小生成树中的边是(1,2,2) (2,3,5) (4,1,3)
对于输入的第三条边(3,4,7),树上3->4的路径是3->2->1->4,边权分别是5,2,3,最小值是2。

思路

最小生成树和树上路径信息维护的结合,两个模板套在一起即可

代码示例

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+50;
const int maxm=2e5+50;
const int inf=0x3fffffff;int n,m;//n为点数 m为边数struct eee{//解决lcaint from,to,dist;eee(int u,int v,int w):from(u),to(v),dist(w){}
};vector<eee> edges;//边的具体信息
vector<int> GG[maxn];//边的编号void addEdge(int u,int v,int w){//vector邻接表edges.push_back(eee(u,v,w));edges.push_back(eee(v,u,w));int size=edges.size();GG[u].push_back(size-2);GG[v].push_back(size-1);
}const int maxlog=30;
int grand[maxn][maxlog];
int gmax[maxn][maxlog];
int depth[maxn];
int s;//倍增最大步数
int root;//根节点void dfs(int x)//预处理
{for(int i=1;i<=s;++i){grand[x][i]=grand[grand[x][i-1]][i-1];gmax[x][i]=max(gmax[x][i-1],gmax[grand[x][i-1]][i-1]);if(!grand[x][i]) break;}for(int i=0;i<GG[x].size();i++){eee & e=edges[GG[x][i]];if(e.to!=grand[x][0]){depth[e.to]=depth[x]+1;grand[e.to][0]=x;gmax[e.to][0]=e.dist;dfs(e.to);}}
}void init()
{s=floor(log(n+0.0)/log(2.0));depth[0]=-1;//memset(depth,0,sizeof(depth));memset(grand,0,sizeof(grand));memset(gmax,0,sizeof(gmax));root=1;dfs(root);//以1为根结点建树
}int lca(int a,int b,int &maxx)//最大值
{if(depth[a]>depth[b]) swap(a,b);maxx=gmax[b][0];//之前的bug,应该放更深的bint dre=depth[b]-depth[a];for(int i=s;i>=0;--i){if(dre&(1<<i)) maxx=max(maxx,gmax[b][i]),b=grand[b][i];}if(a==b) return a;for(int i=s;i>=0;i--)if(grand[a][i]!=grand[b][i]){maxx=max(maxx,gmax[a][i]),maxx=max(maxx,gmax[b][i]);a=grand[a][i],b=grand[b][i];}maxx=max(maxx,gmax[a][0]);maxx=max(maxx,gmax[b][0]);return grand[a][0];
}typedef struct{//边集数组int beg;int endd;int weight;int flag;//1表示在 0表示不在int order;//进来时的顺序
}Edge;bool cmp(Edge a,Edge b)//边集数组排序
{return a.weight<b.weight;
}bool cmp1(Edge a,Edge b)//原位置排序
{return a.order<b.order;
}typedef struct{Edge xiang[maxm];//边的信息int numVertexes,numEdges;//顶点数和边数
}MGraph;MGraph G;void CreateMGraph()
{for(int i=0;i<m;++i){cin>>G.xiang[i].beg>>G.xiang[i].endd>>G.xiang[i].weight;G.xiang[i].order=i;}G.numEdges=m;G.numVertexes=n;sort(G.xiang,G.xiang+m,cmp);
}int parent[maxm];//辅助并查集int Find(int f)//查找连线顶点的尾部下标
{return parent[f]!=f?parent[f]=Find(parent[f]):f;
}void MiniSpanTree_Kruskal()
{int nn,mm;//int parent[maxm];//定义一数组用来判断边与边是否形成环路for(int i=0;i<G.numVertexes;++i)parent[i]=i;//初始化数组值为ifor(int i=0;i<G.numEdges;++i){//循环每一条边nn=Find(G.xiang[i].beg);mm=Find(G.xiang[i].endd);if(nn!=mm){//假如n与m不等,说明此边没有与现有生成树形成环路parent[nn]=mm;//将此边的结尾顶点放入下标为起点的parent中//表示此顶点已经在生成树集合中//printf("在:(%d,%d) %d\n",G.xiang[i].beg,G.xiang[i].endd,G.xiang[i].weight);//sum+=G.xiang[i].weight;G.xiang[i].flag=1;addEdge(G.xiang[i].beg,G.xiang[i].endd,1000000001-G.xiang[i].weight);//进入lca,注意求最小值,所以拿大值减后求最大值//cout<<G.xiang[i].beg<<' '<<G.xiang[i].endd<<' '<<1000000001-G.xiang[i].weight<<endl;}else{G.xiang[i].flag=0;//不在}//else printf("不在:(%d,%d) %d\n",G.xiang[i].beg,G.xiang[i].endd,G.xiang[i].weight);}//cout<<sum<<endl;//路径和
}int main()
{ios::sync_with_stdio(false);cin>>n>>m;CreateMGraph();//for(int i=0;i<G.numEdges;++i) cout<<G.xiang[i].beg<<" "<<G.xiang[i].endd<<" "<<G.xiang[i].weight<<endl;//cout<<G.numEdges<<G.numVertexes<<endl;MiniSpanTree_Kruskal();//for(int i=0;i<G.numVertexes;++i)//cout<<parent[i]<<' ';sort(G.xiang,G.xiang+m,cmp1);init();int maxx;//生成树上两点间最短边权for(int i=0;i<m;++i){if(G.xiang[i].flag==1){cout<<"Ohyee"<<endl;}else{lca(G.xiang[i].beg,G.xiang[i].endd,maxx);//cout<<lca(u,v,maxx,sum)<<endl;cout<<1000000001-maxx<<endl;//再减去即为最小值}}return 0;
}

17AHU排位赛2 A题(最小生成树、LCA维护树上路径)相关推荐

  1. 17AHU排位赛3 D题 旋转吧!雪月花 ! (DFS序,线段树维护树上最值)

    problem 在一个平面上有n个齿轮,每个齿轮都有自己的初始半径 ri r_i .有n-1对齿轮是互相嵌在一起的,即它们拥有相同的线速度.如果将n个齿轮当作n个点,将n-1条相嵌关系当作n-1条边, ...

  2. 对LCA、树上倍增、树链剖分(重链剖分长链剖分)和LCT(Link-Cut Tree)的学习

    LCA what is LCA & what can LCA do LCA(Lowest Common Ancestors),即最近公共祖先 在一棵树上,两个节点的深度最浅的公共祖先就是 L ...

  3. 【最小生成树+LCA】Imperial roads

    http://codeforces.com/gym/101889 I 先跑一遍最小生成树,把经过的边和答案记录下来 对于每个询问的边,显然如果处于MST中,答案不变 如果不在MST中,假设这条边连上了 ...

  4. 线段树合并与分裂维护树上最长上升子序列 + 点分治删点 ---- 2021 牛客多校第一场 C - Cut the tree(详解)

    题目大意: 给你一个树,树上每个点都有一个权值valnodeval_{node}valnode​,路径(u,v)(u,v)(u,v) 上所有点按顺序有序序列,令f(u,v)f(u,v)f(u,v)是这 ...

  5. 牛客题霸 [矩阵的最小路径和] C++题解/答案

    牛客题霸 [矩阵的最小路径和] C++题解/答案. 题目描述 给定一个 n * m 的矩阵 a,从左上角开始每次只能向右或者向下走,最后到达右下角的位置,路径上所有的数字累加起来就是路径和,输出所有的 ...

  6. 秦始皇修路(最小生成树+LCA)

    [问题描述]   秦朝有N个城市,需要修建一些道路使得任意两个城市之间都可以相互连通.道士徐福生称他可以用法术修路,不花钱,也不用劳动力,但只能修一条,因此需要慎重选择用法术修建哪一条路. 秦始皇不仅 ...

  7. 洛谷1967 火车运输 kruskal求最大生成树 倍增LCA维护最小值

    传送门 其实NOIP某些年的第三题也并不是很难嘛... 题目分析: 题目中要求求出某两点之间可以运输的最大重量,也就是这两个点的某条路径上边权最小的边的权值的最大值 很显然,题目中的运输最大重量与选择 ...

  8. 51nod1743-雪之国度【最小生成树,LCA,并查集】

    正题 题目链接:http://www.51nod.com/Challenge/Problem.html#problemId=1743 题目大意 nnn个点mmm条边的一张图,每次询问要求找出x,yx, ...

  9. codevs1519 过路费(最小生成树+LCA)

    1519 过路费  时间限制: 1 s  空间限制: 256000 KB  题目等级 : 大师 Master 题目描述 Description 在某个遥远的国家里,有 n个城市.编号为 1,2,3,- ...

  10. [究极好题][最小生成树]野餐规划 AcWing347

    一群小丑演员,以其出色的柔术表演,可以无限量的钻进同一辆汽车中,而闻名世界. 现在他们想要去公园玩耍,但是他们的经费非常紧缺. 他们将乘车前往公园,为了减少花费,他们决定选择一种合理的乘车方式,可以使 ...

最新文章

  1. 『TensorFlow』数据读取类_data.Dataset
  2. LRU算法确定最后使用时间的顺序-栈
  3. 数据科学的积累:海平面下的冰山 | 清华信息技术研究院郑方
  4. OPA PropertyStrictEquals match check logic
  5. 栈大小和内存分部问题
  6. php做一个计算日期之间天数,PHP计算任意两个日期之间的天数
  7. sql group by 取每组符合条件_SPL 简化 SQL 案例详解:计算各组前 N 行
  8. 5g组网sa方式的演进_关于5G的SA(独立组网)和NSA(非独立组网),这篇通俗易懂!
  9. unc0ver 越狱工具来袭,免电脑操作,支持 A7-A12,支持iOS11~iOS12.4稳定越狱
  10. matlab曲线 投影,MATLAB地图工具箱学习心得(一)关于分带投影的拼接
  11. 自下而上分析方法-算符优先,LR(0),SLR,LR(1),LALR大全
  12. 多人协作共享画板——多人画板的bug及分析
  13. Dell台式机安装ubuntu系统
  14. mysql ddl过程,MySQL基础教程3-DDL(创建表)
  15. 以极地号为例认识科考船上的各种设备
  16. Kermit文件传输协议
  17. mysql-mmm 故障_mysql-mmm故障解决一例
  18. 使用bat 批处理 创建自己的自启动软件
  19. Python 爬虫 中文乱码一文通
  20. 独家 | 关于数据管理标准化工作的思考

热门文章

  1. 圣安地列斯服务器没有响应,Windows10系统玩不了侠盗猎车圣安地列斯怎么办?解决方案...
  2. Android桌面插件系列
  3. 小米的新logo与戴森的吹风机
  4. 怎么判断自己在不在一家好公司?
  5. 斯蒂文斯理工学院计算机科学硕士,斯蒂文斯理工学院计算机科学computer science专业排名第201~250名(2020THE泰晤士高等教育世界大学排名)...
  6. C# 程序开机自动启动
  7. Python-计算三角形边长和面积
  8. 程序员戴耳机是为了撩妹子?感觉好酷的样子~
  9. php实现页面强制跳转,PHP实现页面跳转的几种方法 - 米扑博客
  10. Android网络框架-Volley实践 使用Volley打造自定义ListView