$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;
}
随机推荐
- jQuery Css类
通过 jQuery,可以很容易地对 CSS 元素进行操作 jQuery 操作 CSS jQuery 拥有若干进行 CSS 操作的方法.我们将学习下面这些: addClass() - 向被选元素添加一个 ...
- Streamy障碍一:大批量条目
- oracle函数 least(exp1,exp2,exp3,……,expn)
[功能]返回表达式列表中值最小的一个.如果表达式类型不同,会隐含转换为第一个表达式类型. [参数]exp1……n,各类型表达式 [返回]exp1类型 [示例] SELECT least(10,32,' ...
- 「BZOJ3694」「FJ2014集训」最短路
「BZOJ3694」「FJ2014集训」最短路 首先树剖没得说了,这里说一下并查集的做法, 对于一条非树边,它会影响的点就只有u(i),v(i)到lca,对于lca-v的路径上所有点x,都可通过1-t ...
- Getting started with the basics of programming exercises_5
1.编写函数,把由十六进制数字组成的字符串转换为对应的整型值 编写函数htoi(s),把由十六进制数字组成的字符串(包含可选的前缀0x或0X)转换为与之等价的整型值.字符串中允许包含的数字包括:0~9 ...
- 为你的 SuperSocket 启用动态语言
步骤如下: 1.添加 DLR (dynamic language runtime) 配置片段; Section 定义: <section name="microsoft.scripti ...
- 【CSS3】精美横向滚动菜单按钮
废话不多说,直接上图: 然后是代码: <!DOCTYPE html> <html> <head> <meta charset="utf-8" ...
- 2013-10-7 设置combboxItem高度的方法
//首先设置一个较大的 ItemHeight 值,比如 20: //然后设置 ComboBox 的 DrawMode 为 OwnerDrawVariable: //再设置DrawItem事件如下 if ...
- java.lang.ClassCastException: com.sun.proxy.$Proxy6 cannot be cast to com.etc.service.serviceImpl.BankServiceImpl
错误原因: java.lang.ClassCastException: com.sun.proxy.$Proxy6 cannot be cast to com.etc.service.serviceI ...
- 4-10 items设计
1,items相当于dict,但是又比字典好 2,parse.urljoin(response.url,post_url)方法,其中image_url是一个域名的话,其中的当前域名就不用再添加. yi ...