$Noip2013/Luogu1967$ 货车运输 最大生成树+倍增$lca$
$Sol$
首先当然是构建一棵最大生成树,然后对于一辆货车的起点和终点倍增跑$lca$更新答案就好.记得预处理倍增的时候不仅要处理走了$2^i$步后是那个点,还有这中间经过的路径权值的最小值以便之后统计答案.
再一看发现这题并没说给的图是联通的,也就是说跑了最大生成树之后可能有若干棵树.所以构树的时候要注意不能随便选一个点构完就不管了,要对每一个联通块都构一次.其他的地方似乎没有因为它有多棵树而有什么不同,只是询问的时候看下是不是一个联通块里的就好.
$Code$
#include<bits/stdc++.h>
#define il inline
#define Rg register
#define go(i,a,b) for(Rg int i=a;i<=b;++i)
#define yes(i,a,b) for(Rg int i=a;i>=b;--i)
#define e(i,u) for(Rg int i=b[u];i;i=a[i].nt)
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
#define db double
#define inf 2147483647
using namespace std;
il int read()
{
Rg int x=0,y=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
return x*y;
}
const int N=10010;
int n,m,q,f[N],b[N],ct,c[N][11],d[N][11],dep[N];
bool vis[N];
struct node{int u,v,w;}eg[N*5];
struct node1{int v,w,nt;}a[N*10];
il bool cmp(node x,node y){return x.w>y.w;}
il int find(int x){if(x==f[x])return x;return f[x]=find(f[x]);}
il void add(int u,int v,int w){a[++ct]=(node1){v,w,b[u]};b[u]=ct;}
il void dfs(int u)
{
vis[u]=1;
e(i,u)
{
Rg int v=a[i].v,w=a[i].w;
if(vis[v])continue;
dep[v]=dep[u]+1;c[v][0]=u;d[v][0]=w;
go(j,1,10)c[v][j]=c[c[v][j-1]][j-1],d[v][j]=min(d[v][j-1],d[c[v][j-1]][j-1]);
dfs(v);
}
}
il int sol(int u,int v)
{
Rg int ret=inf;
if(dep[u]<dep[v])swap(u,v);
yes(j,10,0)
{
if(dep[c[u][j]]>dep[v])ret=min(ret,d[u][j]),u=c[u][j];
}
if(dep[u]>dep[v])ret=min(ret,d[u][0]),u=c[u][0];
if(u==v)return ret;
yes(j,10,0)if(c[u][j]!=c[v][j])ret=min(ret,min(d[u][j],d[v][j])),u=c[u][j],v=c[v][j];
ret=min(ret,min(d[u][0],d[v][0]));
return ret;
}
int main()
{
n=read(),m=read();
go(i,1,n)f[i]=i;
go(i,1,m)eg[i]=(node){read(),read(),read()};
sort(eg+1,eg+m+1,cmp);
go(i,1,m)
{
Rg int u=eg[i].u,v=eg[i].v,w=eg[i].w;
if(find(u)==find(v))continue;
f[find(u)]=find(v);
add(u,v,w),add(v,u,w);
}
go(i,1,n)if(!vis[i])dep[i]=1,dfs(i);
q=read();
while(q--)
{
Rg int u=read(),v=read();
if(find(u)!=find(v))printf("-1\n");
else printf("%d\n",sol(u,v));//cout<<endl;
}
return 0;
}
随机推荐
- TCP/IP,UDP,HTTP,SOCKET之间的区别和关系
TCP/IP TCP/IP代表传输控制协议/网际协议,指的是一系列协组.可分为四个层次:数据链路层.网络层.传输层和应用层. 在网络层:有IP协议.ICMP协议.ARP协议.RARP协议和BOOTP协 ...
- 即插即用,基于阿里云Ganos快速构建云上开源GIS方案
对于轻量级GIS应用,选择具备时空能力的云上数据库再搭配开源GIS软件,能够快速构建稳定.廉价.实用的GIS解决方案.Ganos是阿里云自研时空基础设施(PaaS层)的核心引擎,该引擎整合了云上异构计 ...
- linux服务器时间更新
yum install ntpdate ntpdate ntp1.aliyun.com(阿里云服务器时间)
- Java中Map/List/Set .
很实用,分享一下. 简单版本 复杂版本 参考: http://initbinder.com/articles/cheat-sheet-for-selecting-maplistset-in-java. ...
- ReactDOM & DOM Elements
一.ReactDOM 1.1 render() ReactDOM.render(element,container,[callback]) 在container中渲染一个React元素,然后返回组件一 ...
- C++ sort使用两个参数来排序
排序在编程中经常用到,冒泡法排序时间复杂度高,使用C++库函数sort可以快速排序. 1.必须的头文件#include < algorithm>和using namespace std; ...
- ngRoute
ngRoute 模块中包含以下内容, 名称 所属 作用 ngView DIRECTIVE 提供不同路由模板插入的视图层 $routeProvider PROVIDER 提供路由配置 $route SE ...
- js获取dom节点
var s= document.getElementById("test");del_ff(s); //清理空格var chils= s.childNodes; //得到s的全部子 ...
- js获取当前时间戳以及前一天时间戳
js获取当前时间戳以及前一天时间戳(毫秒) var timestamp = (new Date()).getTime(); console.log(timestamp);//打印当前时间戳 conso ...
- 深入java面向对象四:Java 内部类种类及使用解析(转)
内部类Inner Class 将相关的类组织在一起,从而降低了命名空间的混乱. 一个内部类可以定义在另一个类里,可以定义在函数里,甚至可以作为一个表达式的一部分. Java中的内部类共分为四种: 静态 ...