$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;
}
随机推荐
- @codeforces - 414E@ Mashmokh's Designed Problem
目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一棵 n 个点的树,每个点的儿子是有序的. 现给定 m 次操 ...
- iptables 负裁平衡(Load balancing)
「负戴平衡」的作用是将连線平均分散给一组伺服器,以充分利用资源.最简单的作法是利用「通讯端口转接」技术,使其以循环顺序选择目的地位址. 设定iptables的组态 各家Linux系统的iptables ...
- 学习HTML<audio>标签
首先来看下这个例子: <audio controls autoplay="autoplay"> <source src="horse.ogg" ...
- Android Xutils框架HttpUtil Get请求缓存问题
话说,今天和服务器开发人员小小的逗逼了一下,为啥呢? 话说今天有个"收藏产品"的请求接口,是get request的哦,我客户端写好接口后,点击"收藏按钮",返 ...
- Websocket 单聊功能
单聊代码 import json from flask import Flask,request,render_template from geventwebsocket.handler import ...
- 在 Linux 安装 IIS?
在 Linuxe 安装 IIS? 在群里有人说他的老大让他在 Linux 中安装 IIS. 一群人回复不同的解决方案. 在 Linux 安装虚拟机,再安装 Windows. (哈哈哈) 这个问题虽然有 ...
- cf1234-div3
A 水题 B 直接看2,发现`unordered_map被卡了...` 乖乖离散化 C 有六种水管,可以任意的旋转,使得有一条从(1, 0)到(2, n)的通路. 找规律,当时写D没来得及看 #inc ...
- JavaScript引用类型和基本类型的区别
JavaScript变量可以用来保存的两种类型的值:基本类型值和引用类型值. 基本类型值有5种类型:undefined,null,boolean,number,string 引用类型值有两种类型:函数 ...
- [转]FileDescriptor详解
FileDescriptor是"文件描述符". FileDescriptor可以被用来表示开放的文件,开放的套接字等. 当FileDescriptor表示文件来说,当FIleDes ...
- squid+iptables实现网关防火墙
需求说明:此服务器用作网关.MAIL(开启web.smtp.pop3).FTP.DHCP服务器,内部一台机器(192.168.0.254)对外提供dns服务,为了不让无意者轻易看出此服务器开启了ssh ...