时间限制: 1 s
 空间限制: 256000 KB
 题目等级 : 大师 Master
题目描述 Description

在某个遥远的国家里,有 n个城市。编号为 1,2,3,…,n。这个国家的政府修建了m 条双向道路,每条道路连接着两个城市。政府规定从城市 S 到城市T需要收取的过路费为所经过城市之间道路长度的最大值。如:A到B长度为 2,B到C 长度为3,那么开车从 A经过 B到C 需要上交的过路费为 3。
    佳佳是个做生意的人,需要经常开车从任意一个城市到另外一个城市,因此他需要频繁地上交过路费,由于忙于做生意,所以他无时间来寻找交过路费最低的行驶路线。然而, 当他交的过路费越多他的心情就变得越糟糕。 作为秘书的你,需要每次根据老板的起止城市,提供给他从开始城市到达目的城市,最少需要上交多少过路费。

输入描述 Input Description

第一行是两个整数 n 和m,分别表示城市的个数以及道路的条数。 
    接下来 m 行,每行包含三个整数 a,b,w(1≤a,b≤n,0≤w≤10^9),表示a与b之间有一条长度为 w的道路。
    接着有一行为一个整数 q,表示佳佳发出的询问个数。 
    再接下来 q行,每一行包含两个整数 S,T(1≤S,T≤n,S≠T), 表示开始城市S 和目的城市T。

输出描述 Output Description

输出共q行,每行一个整数,分别表示每个询问需要上交的最少过路费用。输入数据保证所有的城市都是连通的。

样例输入 Sample Input

4 5 
1 2 10 
1 3 20 
1 4 100 
2 4 30 
3 4 10 

1 4 
4 1

样例输出 Sample Output

20 
20

数据范围及提示 Data Size & Hint

对于 30%的数据,满足 1≤ n≤1000,1≤m≤10000,1≤q≤100; 
对于 50%的数据,满足 1≤ n≤10000,1≤m≤10000,1≤q≤10000; 
对于 100%的数据,满足 1≤ n≤10000,1≤m≤100000,1≤q≤10000;

 
最小生成树+LCA
#include <algorithm>
#include <ctype.h>
#include <cstdio>
#define M 205005 void read(int &x)
{
x=;bool f=;
register char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=;
for(; isdigit(ch);ch=getchar()) x=x*+ch-'';
x=f?(~x)+:x;
}
struct Edge
{
int x,y,z;
bool operator <(Edge a)const
{
return z<a.z;
}
}e[M];
struct NewEdge
{
int next,to,value;
NewEdge(int next=,int to=,int value=) : next(next),to(to),value(value) {}
}edge[M<<];
using namespace std;
int f[M][],dep[M],dad[M][],head[M<<],cnt,n,m,q,fa[M];
int find_(int x) {return fa[x]==x?x:fa[x]=find_(fa[x]);}
void ins(int u,int v,int w)
{
edge[++cnt]=NewEdge(head[u],v,w);
head[u]=cnt;
}
void dfs(int x)
{
dep[x]=dep[dad[x][]]+;
for(int i=;dad[x][i];i++)
{
dad[x][i+]=dad[dad[x][i]][i];
f[x][i+]=max(f[dad[x][i]][i],f[x][i]);
}
for(int u=head[x];u;u=edge[u].next)
{
int v=edge[u].to;
if(dad[x][]!=v)
{
dad[v][]=x;
f[v][]=edge[u].value;
dfs(v);
}
}
}
int lca(int x,int y)
{
int ans=;
if(dep[x]<dep[y]) swap(x,y);
for(int i=;i>=;i--)
{
if(dep[dad[x][i]]>=dep[y])
{
ans=max(ans,f[x][i]);
x=dad[x][i];
}
}
if(x==y) return ans;
for(int i=;i>=;i--)
{
if(dad[x][i]!=dad[y][i])
{
ans=max(ans,f[x][i]);
ans=max(ans,f[y][i]);
x=dad[x][i];
y=dad[y][i];
}
}
return max(max(f[x][],f[y][]),ans);
}
int main()
{
read(n);
read(m);
for(int i=;i<=n;i++)
fa[i]=i;
for(int i=;i<=m;i++)
{
read(e[i].x);
read(e[i].y);
read(e[i].z);
if(e[i].x>e[i].y) swap(e[i].x,e[i].y);
}
sort(e+,e++m);
int sum=;
for(int i=;i<=m;i++)
{
int fx=find_(e[i].x),fy=find_(e[i].y);
if(fx!=fy)
{
fa[fy]=fx;
ins(e[i].x,e[i].y,e[i].z);
ins(e[i].y,e[i].x,e[i].z);
sum++;
if(sum==n-) break;
}
}
dfs();
read(q);
for(int x,y;q--;)
{
read(x);
read(y);
printf("%d\n",lca(x,y));
}
return ;
}

最新文章

  1. 安装android studio
  2. codevs 1690 开关灯 线段树水题
  3. rails里routes配置文件里的resources和resource的区别
  4. 剑指 offer set 7 调整数组顺序使奇数位于偶数前面
  5. 路由器之VPN应用与配置指南
  6. jQuery Tools:Web开发必备的 jQuery UI 库
  7. 基于 Webpack &amp; Vue &amp; Vue-Router 的 SPA 初体验
  8. cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第六步---炮台&amp;amp;点击炮台加入英雄&amp;amp;英雄升级
  9. Gentoo/Arch常用软件配置
  10. Android开发学习之路--Android系统架构初探
  11. 自制无线共享工具C++源代码
  12. 删除U8中单据已经审核完成但工作流未完成的任务
  13. June 17. 2018, Week 25th. Sunday
  14. 每天一个Linux命令(03):du命令
  15. Golang入门教程(十七)Linux/Windows下快速搭建和配置NSQ
  16. 记录MySQL的一些基础操作
  17. CentOS安装jdk的三种方法
  18. IOS内存约定-【ios】
  19. 30分钟搞定后台登录界面(103个后台PSD源文件、素材网站)
  20. 日志_测试代码_Qt532

热门文章

  1. 关于encodeURIComponent的用法
  2. 安装YouCompleteMe时,编译依赖的python版本不对
  3. [Java] String类, StringBuffer类
  4. Codechef WEASELSC
  5. 1004 n^n的末位数字
  6. 所读STL文章摘要集结
  7. 求一元二次方程的根【double型的0输出%.2lf为-0.00】
  8. python __builtins__ filter类 (24)
  9. bzoj 4975: [Lydsy1708月赛]区间翻转【博弈论】
  10. python 合集set,交集,并集,差集,对称差集别搞混