题目大意:
一个$n(n\le15000)$个点,$m(m\le30000)$条边的无向图,每条边有一个边权$w_i$,$q(q\le20000)$次询问,每次询问点$(u,v)$所有路径中权值最大的边最小值是多少。思路:
LCA模板题,这里考虑使用Kruskal重构树。对于排完序的边新建一个虚点,权值为边权,作为两个顶点子树的父结点。询问时相当于询问重构树上两点LCA点权。1 #include2 #include 3 #include 4 #include 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 >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]) 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