$Noip2013/Luogu1967$ 货车运输 最大生成树+倍增$lca$
Posted forward777
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了$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 nodeint u,v,w;eg[N*5]; struct node1int 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;
以上是关于$Noip2013/Luogu1967$ 货车运输 最大生成树+倍增$lca$的主要内容,如果未能解决你的问题,请参考以下文章
NOIP 2013 提高组 洛谷P1967 货车运输 (Kruskal重构树)
luogu1967noip2013 货车运输 [生成树kruskal LCA ]