【BZOJ3732】 Network Kruskal+倍增lca

Description

给你N个点的无向图 (1 <= N <= 15,000),记为:1…N。 
图中有M条边 (1 <= M <= 30,000) ,第j条边的长度为: d_j ( 1 < = d_j < = 1,000,000,000).

现在有 K个询问 (1 < = K < = 15,000)。 
每个询问的格式是:A B,表示询问从A点走到B点的所有路径中,最长的边最小值是多少?

Input

第一行: N, M, K。 
第2..M+1行: 三个正整数:X, Y, and D (1 <= X <=N; 1 <= Y <= N). 表示X与Y之间有一条长度为D的边。 
第M+2..M+K+1行: 每行两个整数A 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

HINT

1 <= N <= 15,000

1 <= M <= 30,000

1 <= d_j <= 1,000,000,000

1 <= K <= 15,000

Source

找到一个最小生成树,然后lca就好。。。肉眼查错大法好。。
 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define M 30010
#define N 15010
#define inf 0x7fffffff
using namespace std;
struct node1{int x,y,v;}d[M];
struct node2{int next,v,to;}e[M];
int n,m,k,cnt;
int fa[N][],fa_max[N][],belong[N],dpt[N],head[N];
inline int read() {char c; int ans=; while ((c=getchar())==' ' || c=='\n' || c=='\r'); ans=c-''; while (isdigit(c=getchar())) ans=ans*+c-''; return ans;}
bool cmp(node1 a,node1 b){return a.v<b.v;}
void adde(int x,int y,int z) {cnt++; e[cnt].next=head[x]; head[x]=cnt; e[cnt].to=y; e[cnt].v=z;}
int findfa(int x)
{
if (!belong[x] || belong[x]==x) return belong[x]=x;
else return belong[x]=findfa(belong[x]);
}
void bfework(int x)
{
dpt[x]=dpt[fa[x][]]+;
for (int i=head[x];i;i=e[i].next)
{
if (e[i].to==fa[x][]) continue;
fa[e[i].to][]=x;
fa_max[e[i].to][]=e[i].v;
bfework(e[i].to);
}
}
int query(int x,int y)
{
int ans=-inf;
if (dpt[x]<dpt[y]) swap(x,y);
for (int i=;~i;i--)
if (dpt[fa[x][i]]>=dpt[y])
ans=max(ans,fa_max[x][i]),x=fa[x][i];
if (x==y) return ans;
for (int i=;~i;i--)
if (fa[x][i]!=fa[y][i])
{
ans=max(max(fa_max[x][i],fa_max[y][i]),ans);
x=fa[x][i];
y=fa[y][i];
}
ans=max(max(fa_max[x][],fa_max[y][]),ans);
return ans;
}
int main()
{
n=read(); m=read(); k=read();
for (int i=;i<=m;i++) {d[i].x=read(); d[i].y=read(); d[i].v=read();}
sort(d+,d+m+,cmp);
for (int i=;i<=m;i++)
{
int fax=findfa(d[i].x),fay=findfa(d[i].y);
if (fax!=fay)
{
belong[fax]=fay;
adde(d[i].x,d[i].y,d[i].v);
adde(d[i].y,d[i].x,d[i].v);
}
}
bfework();
for (int i=;i<=;i++)
for (int j=;j<=n;j++)
fa[j][i]=fa[fa[j][i-]][i-],fa_max[j][i]=max(fa_max[j][i-],fa_max[fa[j][i-]][i-]);
for (int i=;i<=k;i++)
{
int x,y;
x=read(); y=read();
printf("%d\n",query(x,y));
}
// for (int i=1;i<=n;i++) printf("%d ",dpt[i]);
// printf("%d ",fa_max[5][1]);
return ;
}
上一篇:前端换mac可以参考搭一下简单的环境


下一篇:exsi主机之间使用scp拷贝文件超时问题