bzoj3732-Network

题意

给出一个 \(n\) 个点 \(m\) 条边的无向图,\(q\) 次询问 \((x,y)\) 的所有路径中最长边最小是多少。

\(n,m,q\le 3\times 10^4\)

分析

题意明显是最小生成树上两点之间最大边权。有三种做法。当模板题玩一玩就好了。

第一种是简单的最小生成树上倍增,复杂度为 \(O(n\log n)\)

第二种是最小生成树上用lct求最大边权,复杂度为 \(O(n\log n)\)

第三种是kruskal重构树上倍增lca,复杂度为 \(O(n\log n)\)

代码

这是第三种做法。

#include<bits/stdc++.h>
using namespace std;
inline char nchar() {
	static const int bufl=1<<20;
	static char buf[bufl],*a,*b;
	return a==b && (b=(a=buf)+fread(buf,1,bufl,stdin),a==b)?EOF:*a++;
}
inline int read() {
	int x=0,f=1;
	char c=nchar();
	for (;!isdigit(c);c=nchar()) if (c=='-') f=-1;
	for (;isdigit(c);c=nchar()) x=x*10+c-'0';
	return x*f;
}
const int maxn=3e4+1;
const int maxm=3e4+1;
const int maxj=15;
int n,m,q,tot;
struct edge {
	int x,y,w;
	inline bool operator < (const edge &a) const {return w<a.w;}
} e[maxm];
int f[maxn];
int find(int x) {return f[x]==x?x:f[x]=find(f[x]);}
namespace tree {
	vector<int> g[maxn];
	int w[maxn],f[maxn][maxj],dep[maxn];
	inline void add(int x,int y) {g[x].push_back(y);}
	void dfs(int x,int fa) {
		dep[x]=dep[fa]+1;
		f[x][0]=fa;
		for (int j=1;j<maxj;++j) f[x][j]=f[f[x][j-1]][j-1];
		for (vector<int>::iterator it=g[x].begin();it!=g[x].end();++it) dfs(*it,x);
	}
	inline int lca(int x,int y) {
		if (dep[x]<dep[y]) swap(x,y);
		for (int j=maxj-1;j>=0;--j) if (dep[f[x][j]]>=dep[y]) x=f[x][j];
		if (x==y) return x;
		for (int j=maxj-1;j>=0;--j) if (f[x][j]!=f[y][j]) x=f[x][j],y=f[y][j];
		return f[x][0];
	}
}
int main() {
#ifndef ONLINE_JUDGE
	freopen("test.in","r",stdin);
#endif
	tot=n=read(),m=read(),q=read();
	for (int i=1;i<=m;++i) {
		int x=read(),y=read(),w=read();
		e[i]=(edge){x,y,w};
	}
	for (int i=1;i<(n<<1);++i) f[i]=i;
	sort(e+1,e+m+1);
	for (int i=1;i<=m;++i) {
		int &x=e[i].x,&y=e[i].y,&w=e[i].w;
		int fx=find(x),fy=find(y);
		if (fx!=fy) {
			f[fx]=f[fy]=++tot;
			tree::w[tot]=w;
			tree::add(tot,fx),tree::add(tot,fy);
		}
	}
	tree::dfs(tot,tot);
	while (q--) {
		int x=read(),y=read();
		int ans=tree::w[tree::lca(x,y)];
		printf("%d\n",ans);
	}
	return 0;
}
posted @ 2017-08-06 19:12  permui  阅读(160)  评论(0编辑  收藏  举报