【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。

貌似最小生成树就搞定了啊,这么水的吗

但我就要练 K r u s c a l Kruscal 重构树你管我?

#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';
	}
}

猜你喜欢

转载自blog.csdn.net/qq_42555009/article/details/86651315