【NOIP2013提高组】DAY1T3—货车运输(Kruscal重构树)
描述
A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路。每一条道路对车辆都有重量限制,简称限重。现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物?
输入
输入文件第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道
路。 接下来 m 行每行 3 个整数 x、 y、 z,每两个整数之间用一个空格隔开,表示从 x 号城市到 y 号城市有一条限重为 z 的道路。注意: x 不等于 y,两座城市之间可能有多条道路 。
接下来一行有一个整数 q,表示有 q 辆货车需要运货。
接下来 q 行,每行两个整数 x、y,之间用一个空格隔开,表示一辆货车需要从 x 城市运输货物到 y 城市,注意: x 不等于 y 。
输出
每行一个整数,表示对于每一辆货车,它的最大载重是多少。如果货
车不能到达目的地,输出-1。
样例输入
4 3
1 2 4
2 3 3
3 1 1
3
1 3
1 4
1 3
样例输出
3
-1
3
提示
对于 30%的数据,0 < n < 1,000,0 < m < 10,000,0 < q< 1,000;
对于 60%的数据,0 < n < 1,000,0 < m < 50,000,0 < q< 1,000;
对于 100%的数据,0 < n < 10,000,0 < m < 50,000,0 < q< 30,000,0 ≤ z ≤ 100,000。
貌似最小生成树就搞定了啊,这么水的吗
但我就要练重构树你管我?
#include<bits/stdc++.h>
using namespace std;
#define mod 1000000007
#define ll long long
inline int read(){
char ch=getchar();
int res=0;
while(!isdigit(ch))ch=getchar();
while(isdigit(ch)) res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
return res;
}
int adj[370005],nxt[340005],to[340005],dep[370005],val[340005],cnt,tot,fa[370005],son[370005],fath[370005],siz[370005],n,m,q,top[370005];
struct edge{
int u,v,w;
}e[100006];
ll A,B,C,P,ans;
inline int rnd(){
return A=(A*B+C)%P;
}
inline bool comp(const edge &a,const edge &b){
return a.w>b.w;
}
inline void addedge(int u,int v){
nxt[++cnt]=adj[u],adj[u]=cnt,to[cnt]=v;
nxt[++cnt]=adj[v],adj[v]=cnt,to[cnt]=u;
}
inline void dfs1(int u,int father){
siz[u]=1;
for(int e=adj[u];e;e=nxt[e]){
int v=to[e];
if(v==father)continue;
fa[v]=u;
dep[v]=dep[u]+1;
dfs1(v,u);
siz[u]+=siz[v];
if(siz[v]>siz[son[u]])son[u]=v;
}
}
inline void dfs2(int u,int tp){
top[u]=tp;
if(son[u])dfs2(son[u],tp);
for(int e=adj[u];e;e=nxt[e]){
int v=to[e];
if(v==fa[u]||v==son[u])continue;
dfs2(v,v);
}
}
inline int find(int x){
return fath[x]==x?x:fath[x]=find(fath[x]);
}
inline int lca(int u,int v){
while(top[u]!=top[v]){
if(dep[top[u]]>dep[top[v]])u=fa[top[u]];
else v=fa[top[v]];
}
if(dep[u]<dep[v])return u;
return v;
}
int main(){
tot=n=read(),m=read();
for(int i=1;i<=n;++i)fath[i]=i;
for(int i=1;i<=m;++i){
e[i].u=read(),e[i].v=read(),e[i].w=read();
}
sort(e+1,e+1+m,comp);
for(int i=1;i<=m;++i){
int f1=find(e[i].u),f2=find(e[i].v);
if(f1!=f2){
fath[f1]=fath[f2]=fath[++tot]=tot;
val[tot]=e[i].w;
addedge(f1,tot),addedge(f2,tot);
}
}
dfs1(tot,0),dfs2(tot,tot);
q=read();
for(int i=1;i<=q;++i){
int u=read(),v=read();
if(find(u)==find(v))
cout<<val[lca(u,v)]<<endl;
else cout<<"-1"<<'\n';
}
}