#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define MAXN 10005
#define MAXM 100005 using namespace std; struct Edge { int from; int to; int val; int next; }; int n;
int m;
int q;
int cnt;
int num;
int f[MAXN];
int lv[MAXN];
int vis[MAXN];
int dis[MAXN];
int pre[MAXN];
int head[MAXN]; Edge s[MAXM],edge[MAXM]; inline bool cmp(Edge x,Edge y) { return x.val>y.val; } inline int find(int x)
{
if (f[x]!=x) return f[x]=find(f[x]);
return f[x];
} inline void add(int u,int v,int w)
{
edge[++cnt].from=u;
edge[cnt].to=v;
edge[cnt].val=w;
edge[cnt].next=head[u];
head[u]=cnt; return ;
} inline void dfs(int u)
{
for (int i=head[u];i;i=edge[i].next)
{
int v=edge[i].to;
if (!vis[v])
{
pre[v]=u; vis[v]=;
dis[v]=min(dis[v],edge[i].val);
lv[v]=lv[u]+; dfs(v);
}
} return ;
} inline int work(int x,int y)
{
int ans=;
while(lv[x]>lv[y]) ans=min(ans,dis[x]),x=pre[x];
while(lv[y]>lv[x]) ans=min(ans,dis[y]),y=pre[y];
while(x!=y) ans=min(ans,min(dis[x],dis[y])),x=pre[x],y=pre[y];
return ans;
} inline void solve()
{
scanf("%d%d",&n,&m); memset(dis,0x7f,sizeof(dis));
for (int i=;i<=n;i++) f[i]=i;
for (int i=;i<=m;i++)
scanf("%d%d%d",&s[i].from,&s[i].to,&s[i].val);
sort(s+,s++m,cmp); num=; cnt=;
for (int i=;i<=m&&num!=n-;i++)
{
int fa=find(s[i].from); int fb=find(s[i].to);
if (fa!=fb)
{
f[fa]=fb; num++;
add(s[i].from,s[i].to,s[i].val);
add(s[i].to,s[i].from,s[i].val);
}
} scanf("%d",&q); memset(vis,,sizeof(vis));
for (int i=;i<=n;i++)
if (!vis[i]) pre[i]=,lv[i]=vis[i]=,dfs(i);
for (int i=;i<=q;i++)
{
int a; int b; scanf("%d%d",&a,&b);
int fa=find(a); int fb=find(b);
if (fa!=fb) printf("-1\n");
else printf("%d\n",work(a,b));
} return ;
} int main()
{
solve();
return ;
}
废话我就不多说了 最初这道题写的是最大生成树加DFS搜索的 只能得到六十分 后来改成DFS的预处理 预处理的复杂度是O(n)的。
然后对于每一次询问 我这个算法的时间复杂度最坏是O(n)的。 也就是一棵树有两条链 询问的两个点分别是两条链底部的点。
不过数据显然没有这么水的  所以复杂度一般低于O(n)。 
说一说做法哈  先预处理所有的边 求出最大生成树 没有的话无所谓 只要所有的边扫一下 判边的话我用的是并查集维护 
把可以要的边留下就好 然后把这些边连起来
 对于每一个没有搜索过的点就去DFS搜一下 对于搜到的每一个节点要做一个等级标记 根节点等级是1 根节点的所有子节点等级是2 以此类推
DFS过程中记录一下每个点的前驱 以及每个点到它父亲的路径的权值 最后对于每一个询问AB两点
我用语言是不好说的 详情请看代码中的work代码 应该是非常容易理解的 嗯~ o(* ̄▽ ̄*)o 小编就先说到这里吧
如果看了有什么不懂的地方就在下面评论吧 小编会在12小时内给你满意的答复的 谢谢大家o(* ̄▽ ̄*)ブ

最新文章

  1. 如何在IntelliJ IDEA删除Project
  2. vue服务端渲染
  3. C++ 实现 发送HTTP Get/Post请求 good
  4. HDU 1226 BFS
  5. swift material
  6. delphi调用java编写的webservice
  7. TCP/IP 标志位 SYN ACK RST UTG PSH FIN
  8. ASP.NET脚本过滤-防止跨站脚本攻击[转]
  9. 我的JS 中级学习篇
  10. Linux误删C基本运行库libc.so.6处理方法
  11. 使用sql语句获取数据库表的信息
  12. iOS逆向开发(2):获取APP的类声明 | class-dump | dumpdecrypted
  13. [译]MediatR, FluentValidation, and Ninject using Decorators
  14. nginx 开启高效文件传输模式
  15. cloudera安装笔记
  16. Junit进行单元测试
  17. Android广播BroadcastReceiver
  18. 关于拉格朗日乘子法与KKT条件
  19. python模块介绍-locustio:性能测试工具locustio
  20. JVM-内存回收算法--复制算法

热门文章

  1. django对数据查询结果进行排序的方法
  2. Ubuntu16.04安装docker
  3. .NET对象与Windows句柄(一):句柄的基本概念
  4. Oracle实战训练——ATM取款机业务
  5. 6.Linux的文件权限与目录配置
  6. SSR———团队作业:小型论坛的设计与初步实现
  7. 关于问题ld:library not found for -lXXX的错误
  8. keepalived mariadb 主主
  9. shell 除法 小数点
  10. java 读写文件