【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
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
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就好。。。肉眼查错大法好。。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <cmath> 6 #define M 30010 7 #define N 15010 8 #define inf 0x7fffffff 9 using namespace std; 10 struct node1{int x,y,v;}d[M]; 11 struct node2{int next,v,to;}e[M]; 12 int n,m,k,cnt; 13 int fa[N][20],fa_max[N][20],belong[N],dpt[N],head[N]; 14 inline int read() {char c; int ans=0; while ((c=getchar())==' ' || c=='\n' || c=='\r'); ans=c-'0'; while (isdigit(c=getchar())) ans=ans*10+c-'0'; return ans;} 15 bool cmp(node1 a,node1 b){return a.v<b.v;} 16 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;} 17 int findfa(int x) 18 { 19 if (!belong[x] || belong[x]==x) return belong[x]=x; 20 else return belong[x]=findfa(belong[x]); 21 } 22 void bfework(int x) 23 { 24 dpt[x]=dpt[fa[x][0]]+1; 25 for (int i=head[x];i;i=e[i].next) 26 { 27 if (e[i].to==fa[x][0]) continue; 28 fa[e[i].to][0]=x; 29 fa_max[e[i].to][0]=e[i].v; 30 bfework(e[i].to); 31 } 32 } 33 int query(int x,int y) 34 { 35 int ans=-inf; 36 if (dpt[x]<dpt[y]) swap(x,y); 37 for (int i=14;~i;i--) 38 if (dpt[fa[x][i]]>=dpt[y]) 39 ans=max(ans,fa_max[x][i]),x=fa[x][i]; 40 if (x==y) return ans; 41 for (int i=14;~i;i--) 42 if (fa[x][i]!=fa[y][i]) 43 { 44 ans=max(max(fa_max[x][i],fa_max[y][i]),ans); 45 x=fa[x][i]; 46 y=fa[y][i]; 47 } 48 ans=max(max(fa_max[x][0],fa_max[y][0]),ans); 49 return ans; 50 } 51 int main() 52 { 53 n=read(); m=read(); k=read(); 54 for (int i=1;i<=m;i++) {d[i].x=read(); d[i].y=read(); d[i].v=read();} 55 sort(d+1,d+m+1,cmp); 56 for (int i=1;i<=m;i++) 57 { 58 int fax=findfa(d[i].x),fay=findfa(d[i].y); 59 if (fax!=fay) 60 { 61 belong[fax]=fay; 62 adde(d[i].x,d[i].y,d[i].v); 63 adde(d[i].y,d[i].x,d[i].v); 64 } 65 } 66 bfework(1); 67 for (int i=1;i<=14;i++) 68 for (int j=1;j<=n;j++) 69 fa[j][i]=fa[fa[j][i-1]][i-1],fa_max[j][i]=max(fa_max[j][i-1],fa_max[fa[j][i-1]][i-1]); 70 for (int i=1;i<=k;i++) 71 { 72 int x,y; 73 x=read(); y=read(); 74 printf("%d\n",query(x,y)); 75 } 76 // for (int i=1;i<=n;i++) printf("%d ",dpt[i]); 77 // printf("%d ",fa_max[5][1]); 78 return 0; 79 }
—Anime Otaku Save The World.