Time Limit: 10 Sec
Memory Limit: 128 MB
Description
给你
N
N
N个点的无向图
(
1
<
=
N
<
=
15
,
000
)
(1 <= N <= 15,000)
(1<=N<=15,000),记为:
1
…
N
1…N
1…N。
图中有
M
M
M条边
(
1
<
=
M
<
=
30
,
000
)
(1 <= M <= 30,000)
(1<=M<=30,000),第
j
j
j条边的长度为:
d
j
(
1
<
=
d
j
<
=
1
,
000
,
000
,
000
)
d_j ( 1 < = d_j < = 1,000,000,000)
dj(1<=dj<=1,000,000,000).
现在有
K
K
K个询问
(
1
<
=
K
<
=
20
,
000
)
(1 < = K < = 20,000)
(1<=K<=20,000)。
每个询问的格式是:
A
A
A
B
B
B,表示询问从
A
A
A点走到
B
B
B点的所有路径中,最长的边最小值是多少?
Input
第一行:
N
,
M
,
K
N, M, K
N,M,K。
第
2..
M
+
1
2..M+1
2..M+1行: 三个正整数:
X
,
Y
,
X, Y,
X,Y, and
D
(
1
<
=
X
<
=
N
;
1
<
=
Y
<
=
N
)
D (1 <= X <=N; 1 <= Y <= N)
D(1<=X<=N;1<=Y<=N). 表示
X
X
X与
Y
Y
Y之间有一条长度为
D
D
D的边。
第
M
+
2..
M
+
K
+
1
M+2..M+K+1
M+2..M+K+1行: 每行两个整数
A
A
A
B
B
B,表示询问从A点走到B点的所有路径中,最长的边最小值是多少?
Output
对每个询问,输出最长的边最小值是多少。
Sample Input
6 6 8
1 2 5
2 3 4
3 4 3
1 4 8
2 5 7
4 6 2
1 2
1 3
1 4
2 3
2 4
5 1
6 2
6 1
Sample Output
5
5
5
4
4
7
4
5
题解:
最小的最大值一定在最小生成树上(正论!)
那就直接kruskal完加个lca就行了
吐槽:
bzoj这道题的数据居然没有EOF,难受
#include<bits/stdc++.h>
#define LiangJiaJun main
using namespace std;
int n,m,k;
struct edge{
int to,nt,w;
}e[200004];
struct Ds{
int u,v,w;
}a[200004];
inline bool dex(Ds A,Ds B){return A.w<B.w;}
int ne,h[30004];
int f[30004],d[30004][24],fa[30004][24],depth[30004];
int Find(int x){return f[x]==x?x:f[x]=Find(f[x]);}
void add(int u,int v,int w){
e[++ne].to=v;e[ne].w=w;e[ne].nt=h[u];
h[u]=ne;
}
void dfs(int x){
for(int i=1;i<=20;i++){
fa[x][i]=fa[fa[x][i-1]][i-1];
d[x][i]=max(d[x][i-1],d[fa[x][i-1]][i-1]);
}
for(int i=h[x];i;i=e[i].nt){
if(!depth[e[i].to]){
depth[e[i].to]=depth[x]+1;
d[e[i].to][0]=e[i].w;
fa[e[i].to][0]=x;
dfs(e[i].to);
}
}
}
int lca(int u,int v){
if(depth[u]<depth[v])swap(u,v);
int dva=depth[u]-depth[v];
for(int i=0;i<=20;i++){
if(dva&(1<<i))u=fa[u][i];
}
for(int i=20;i>=0;i--){
if(fa[u][i]!=fa[v][i]){
u=fa[u][i];
v=fa[v][i];
}
}
if(u==v)return u;
else return fa[u][0];
}
int ask(int x,int t){
int dva=depth[x]-depth[t];
int ans=0;
for(int i=0;i<=20;i++){
if(dva&(1<<i)){
ans=max(ans,d[x][i]);
x=fa[x][i];
}
}
return ans;
}
int w33ha(){
ne=0;
memset(h,0,sizeof(h));
memset(depth,0,sizeof(depth));
for(int i=1;i<=n;i++)f[i]=i;
for(int i=1;i<=m;i++)scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].w);
sort(a+1,a+m+1,dex);
for(int i=1;i<=m;i++){
int p=Find(a[i].u),q=Find(a[i].v);
if(p!=q){
add(a[i].u,a[i].v,a[i].w);
add(a[i].v,a[i].u,a[i].w);
f[p]=q;
}
}
for(int i=1;i<=n;i++){
if(!depth[i]){
depth[i]=1;
dfs(i);
}
}
while(k--){
int a,b,t;
scanf("%d%d",&a,&b);
t=lca(a,b);
printf("%d\n",max(ask(a,t),ask(b,t)));
}
return 0;
}
int LiangJiaJun(){
scanf("%d%d%d",&n,&m,&k);
w33ha();
return 0;
}