UVA - 11354Bond最小生成树,LCA寻找最近公共祖先
来源:互联网 发布:无人机编队表演算法 编辑:程序博客网 时间:2024/06/11 05:35
看懂题目意思,他的意思是求将所有的城市走一遍,危险度最小,并且给
你两个s,t后让你求在走的时候,从s到t过程中危险度最大的值,并输出它,
然后就是如何解决了,这个题目可以说简单,也可以说难
通过思考可以知道s到t的路径进行遍历就是所谓的答案了
所以通过LCA算法就可以解决问题,大家可以去看看LCA在图论上的算法
/*Author: 2486Memory: 0 KBTime: 2222 MSLanguage: C++11 4.8.2Result: AcceptedVJ RunId: 4236841Real RunId: 15859210*/#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <queue>#include <vector>using namespace std;const int maxn=50000+5;const int maxm=100000+5;int N,M,m;int par[maxn],dist[maxn],depth[maxn],vis[maxn];struct edge { int u,v,cost; bool operator<(const edge &a)const { return cost<a.cost; }} es[maxm];struct ed { int to,cost; ed(int to,int cost):to(to),cost(cost) {}};vector<ed>G[maxn];void init(int c) { for(int i=0; i<maxn; i++) { par[i]=i; dist[i]=-1; if(c)G[i].clear(); } memset(vis,false,sizeof(vis));}int find(int x) { return par[x]==x?x:par[x]=find(par[x]);}bool same(int x,int y) { return find(x)==find(y);}void unite(int x,int y) { x=find(x); y=find(y); par[x]=y;}int lca(int a, int b) { //a的深度<=b的深度 int m1 = -1; while(depth[a] < depth[b]) { //将深度调到一样 m1 = max(m1, dist[b]); b = par[b]; } while(a != b) {//同时从节点走到祖先节点 m1 = max(m1, dist[a]); m1 = max(m1, dist[b]); a = par[a], b = par[b]; } return m1;}void kj() { sort(es,es+M); init(1); int cnt=0; /**********将组成最小生成树的边全都保存起来*************/ /**********大家都懂,这是Kruskal算法*************/ for(int i=0; i<M; i++) { edge e=es[i]; if(!same(e.v,e.u)) { unite(e.v,e.u); G[e.v].push_back(ed(e.u,e.cost)); G[e.u].push_back(ed(e.v,e.cost)); } } /***********************/ dist[1]=0; depth[1]=0; queue<int>F; F.push(1); vis[1]=true; init(0); /*********这个是很重要的**************/ /*********以1号城市为根节点,然后就是开始遍历形成一棵树**************/ /***********大家可以想象一下,如果城市在一棵树的某个节点上************/ /***********那么什么才是从一个点到另一个点的路径呢?************/ /***********很简单,将他们从他们自己的节点向上递推到两个点的共同祖先就可以了************/ /***********中间经历的就是从一个点到另一个点的路径************/ /***********如此,就直接用队列处理一下即可************/ while(!F.empty()) { int v=F.front(); F.pop(); for(int i=0; i<G[v].size(); i++) { ed e=G[v][i]; if(vis[e.to])continue; vis[e.to]=true; par[e.to]=v;//他的父亲节点 depth[e.to]=depth[v]+1;//他的深度 dist[e.to]=e.cost;//从该节点到父亲节点的危险度 F.push(e.to); } } /***********************/}int main() { int cases=1;//freopen("D://imput.txt","r",stdin); while(~scanf("%d%d",&N,&M)) { for(int i=0; i<M; i++) { scanf("%d%d%d",&es[i].u,&es[i].v,&es[i].cost); } if(cases!=1)printf("\n");//注意题目格式,需要换行 kj(); int s,t; scanf("%d",&m); while(m--) { scanf("%d%d",&s,&t);//读取命令 if(depth[s]>depth[t])swap(s,t); printf("%d\n",lca(s,t)); } cases++; } return 0;}
2 0
- UVA - 11354Bond最小生成树,LCA寻找最近公共祖先
- UVA 11354 Bond(最小生成树+lca+倍增求祖先节点)
- 【UVa】11354 Bond 最小生成树,动态LCA,倍增思想
- UVA 11354 Bond 瓶颈路 最小生成树+LCA类似
- UVA 11354 Bond(最小生成树+LCA倍增)
- UVA 11354 Bond(最小生成树+LCA)
- Uva 11354 Bond(最小生成树+LCA)
- UVa 11354 Bond 最小生成树+LCA倍增
- UVA - 11354 Bond(生成树+LCA)
- 最近公共祖先LCA
- 最近公共祖先(LCA)
- Lca 最近公共祖先
- LCA----最近公共祖先
- LCA (最近公共祖先)
- LCA最近公共祖先
- LCA 最近公共祖先
- 最近公共祖先 LCA
- LCA--最近公共祖先
- 【CSS学习】CSS 边框
- java基本算法题及答案
- Java线程中run和start方法的区别
- vs中编译选项MD、MDd、MT的区别
- 【剑指Offer面试题】 九度OJ1523:从上往下打印二叉树
- UVA - 11354Bond最小生成树,LCA寻找最近公共祖先
- ListView适配器BaseAdapter
- 微软沈向洋:计算机视觉未来在语义层 “两大一精”是关键
- 机试算法讲解: 第49题 动态规划之最长递增子序列问题
- 【练习笔记】剑指offer-面试题7 :用两个栈实现队列
- Cocos2d-x_C++11新特性Lambda表达式
- Matlab中varargin函数
- hdu5319 Painter
- malloc(0)