[BZOJ3732]Network
题目大意:
一个$n(n\le15000)$个点,$m(m\le30000)$条边的无向图,每条边有一个边权$w_i$,$q(q\le20000)$次询问,每次询问点$(u,v)$所有路径中权值最大的边最小值是多少。
思路:
LCA模板题,这里考虑使用Kruskal重构树。对于排完序的边新建一个虚点,权值为边权,作为两个顶点子树的父结点。询问时相当于询问重构树上两点LCA点权。
1 #include<cstdio> 2 #include<cctype> 3 #include<cstring> 4 #include<algorithm> 5 inline int getint() { 6 register char ch; 7 while(!isdigit(ch=getchar())); 8 register int x=ch^'0'; 9 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 10 return x; 11 } 12 const int N=3e4,logN=15,M=6e4,M2=3e4; 13 struct Edge { 14 int to,next; 15 }; 16 Edge e[M]; 17 int h[N],sz,tot,n,m,q,val[N],dep[N],anc[N][logN]; 18 inline void add_edge(const int &u,const int &v) { 19 e[sz]=(Edge){v,h[u]};h[u]=sz++; 20 } 21 struct Edge2 { 22 int u,v,w; 23 bool operator < (const Edge2 &another) const { 24 return w<another.w; 25 } 26 }; 27 Edge2 e2[M2]; 28 struct DisjointSet { 29 int anc[N]; 30 DisjointSet() { 31 for(register int i=0;i<N;i++) anc[i]=i; 32 } 33 int find(const int &x) { 34 return x==anc[x]?x:anc[x]=find(anc[x]); 35 } 36 void merge(const int &x,const int &y) { 37 anc[find(x)]=find(y); 38 } 39 bool same(const int &x,const int &y) { 40 return find(x)==find(y); 41 } 42 }; 43 DisjointSet s; 44 inline void kruskal() { 45 std::sort(&e2[0],&e2[m]); 46 for(register int i=0;i<m;i++) { 47 const int u=e2[i].u,v=e2[i].v,w=e2[i].w; 48 if(!s.same(u,v)) { 49 val[++tot]=w; 50 add_edge(tot,s.find(u)); 51 add_edge(tot,s.find(v)); 52 s.merge(u,tot); 53 s.merge(v,tot); 54 } 55 } 56 } 57 inline int log2(const float &x) { 58 return ((unsigned&)x>>23&255)-127; 59 } 60 void dfs(const int &x,const int &par) { 61 dep[x]=dep[anc[x][0]=par]+1; 62 for(register int i=1;i<=log2(dep[x]);i++) { 63 anc[x][i]=anc[anc[x][i-1]][i-1]; 64 } 65 for(register int i=h[x];~i;i=e[i].next) { 66 const int &y=e[i].to; 67 dfs(y,x); 68 } 69 } 70 inline int lca(int x,int y) { 71 if(dep[x]!=dep[y]) { 72 if(dep[x]<dep[y]) std::swap(x,y); 73 for(register int i=log2(dep[x]-dep[y]);~i;i--) { 74 if(dep[anc[x][i]]>=dep[y]) x=anc[x][i]; 75 } 76 } 77 if(x==y) return x; 78 for(register int i=log2(dep[x]);~i;i--) { 79 if(anc[x][i]!=anc[y][i]) { 80 x=anc[x][i]; 81 y=anc[y][i]; 82 } 83 } 84 return anc[x][0]; 85 } 86 int main() { 87 memset(h,-1,sizeof h); 88 n=tot=getint(),m=getint(),q=getint(); 89 for(register int i=0;i<m;i++) { 90 const int u=getint(),v=getint(),w=getint(); 91 e2[i]=(Edge2){u,v,w}; 92 } 93 kruskal(); 94 dfs(tot,0); 95 for(register int i=0;i<q;i++) { 96 printf("%d\n",val[lca(getint(),getint())]); 97 } 98 return 0; 99 }