竟然一次A掉了...
首先用kruskal构建一颗最大生成树。(因为要使最小边最大,则这条边一定在最大生成树上)
于是每次询问就转变为在一棵树上询问两点到LCA的最小边权,用倍增法解决。
顺便复习了一下并查集写法。。。T_T
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> #define F(i,j,n) for(int i=j;i<=n;i++) #define D(i,j,n) for(int i=j;i>=n;i--) #define LL long long #define pa pair<int,int> #define MAXN 10005 #define MAXM 50005 #define INF 1000000000 using namespace std; int n,m,q,x,y,cnt=0; int p[MAXN],d[MAXN],ver[MAXM*2],head[MAXN],f[MAXN][20],g[MAXN][20]; bool vst[MAXN]; struct edge_type { int next,to,w; }e[MAXN*2]; struct data { int x,y,z; }a[MAXM]; int read() { int ret=0,flag=1;char ch=getchar(); while (ch<'0'||ch>'9') {if (ch=='-') flag=-1;ch=getchar();} while (ch>='0'&&ch<='9') {ret=ret*10+ch-'0';ch=getchar();} return ret*flag; } void add_edge(int u,int v,int w) { e[++cnt].to=v; e[cnt].next=head[u]; e[cnt].w=w; head[u]=cnt; } void dfs(int x,int dep) { vst[x]=true; d[x]=dep; for(int i=head[x];i;i=e[i].next) if (!vst[e[i].to]) { f[e[i].to][0]=x; g[e[i].to][0]=e[i].w; dfs(e[i].to,dep+1); } } bool cmp(data d1,data d2) { return d1.z>d2.z; } int find(int x) { if (p[x]!=x) p[x]=find(p[x]); return p[x]; } void kruskal() { sort(a+1,a+m+1,cmp); F(i,1,n) p[i]=i; F(i,1,m) { int fx=find(a[i].x),fy=find(a[i].y); if (fx==fy) continue; p[fx]=fy; add_edge(a[i].x,a[i].y,a[i].z); add_edge(a[i].y,a[i].x,a[i].z); } } int lca_min(int a,int b) { if (a==b) return 0; int ret=INF; if (d[a]<d[b]) swap(a,b); int k=int(log2(d[a])); D(i,k,0) if (d[a]-(1<<i)>=d[b]) { ret=min(ret,g[a][i]); a=f[a][i]; } if (a==b) return ret; D(i,k,0) if (f[a][i]&&f[a][i]!=f[b][i]) { ret=min(ret,min(g[a][i],g[b][i])); a=f[a][i]; b=f[b][i]; } ret=min(ret,min(g[a][0],g[b][0])); return ret; } int main() { memset(head,0,sizeof(head)); memset(vst,false,sizeof(vst)); memset(f,0,sizeof(f)); memset(g,127,sizeof(g)); n=read();m=read(); F(i,1,m) {a[i].x=read();a[i].y=read();a[i].z=read();} q=read(); kruskal(); dfs(1,1); for(int j=1;(1<<j)<=n;j++) F(i,1,n) if (f[i][j-1]) { f[i][j]=f[f[i][j-1]][j-1]; g[i][j]=min(g[i][j-1],g[f[i][j-1]][j-1]); } F(i,1,q) { x=read();y=read(); if (find(x)!=find(y)) puts("-1"); else printf("%d\n",lca_min(x,y)); } return 0; }