貨車運輸
顯然,從一點走到另一點的路徑中,最小值最大的路徑一定在它的最大生成樹上
所以要先求出最大生成樹,再在生成樹上找最近公共祖先,同時求出最小值。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<vector> 5 #include<cmath> 6 using namespace std; 7 8 const int MAXN = 10010 ; 9 10 int n,m,fa[MAXN],f[MAXN][30],deep[MAXN],minn[MAXN][30]; 11 12 bool v[MAXN]; 13 14 struct Edge{ 15 int x; 16 int y; 17 int w; 18 } e[50010]; 19 20 vector<int> son[MAXN],ww[MAXN]; 21 22 bool cmp(Edge x,Edge y) 23 { 24 return x.w>y.w; 25 } 26 27 int find(int x) 28 { 29 if(fa[x]!=x) fa[x]=find(fa[x]); 30 return fa[x]; 31 } 32 33 void init() 34 { 35 scanf("%d%d",&n,&m); 36 for(int i=1;i<=n;i++) 37 fa[i]=i; 38 for(int i=1;i<=m;i++) 39 scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].w); 40 } 41 42 void unionn(int x,int y) 43 { 44 fa[find(x)]=find(y); 45 } 46 47 void mst() 48 { 49 sort(e+1,e+1+m,cmp); 50 int t=0; 51 for(int i=1;i<=m;i++) 52 { 53 int x=e[i].x,y=e[i].y; 54 if(find(x)!=find(y)) 55 { 56 unionn(x,y); 57 t++; 58 son[x].push_back(y); 59 ww[x].push_back(e[i].w); 60 son[y].push_back(x); 61 ww[y].push_back(e[i].w); 62 if(t==n-1) break; 63 } 64 } 65 } 66 67 void build(int now,int d) 68 { 69 v[now]=1; 70 deep[now]=d; 71 for(int i=1;(1<<i)<=deep[now];i++) 72 { 73 minn[now][i]=min(minn[now][i-1],minn[f[now][i-1]][i-1]); 74 f[now][i]=f[f[now][i-1]][i-1]; 75 } 76 for(int i=0;i<son[now].size();i++) 77 if(!v[son[now][i]]) 78 { 79 int u=son[now][i]; 80 minn[u][0]=ww[now][i]; 81 f[u][0]=now; 82 build(u,d+1); 83 } 84 } 85 86 int lca(int x,int y) 87 { 88 int ans=0x7fffffff; 89 if(deep[x]!=deep[y]) 90 { 91 if(deep[x]>deep[y]) swap(x,y); 92 for(int i=20;i>=0;i--) 93 if(deep[f[y][i]]>=deep[x]) 94 { 95 ans=min(ans,minn[y][i]); 96 y=f[y][i]; 97 } 98 } 99 if(x==y) return ans; 100 for(int i=20;i>=0;i--) 101 if(f[x][i]!=f[y][i]) 102 { 103 ans=min(ans,minn[x][i]); 104 ans=min(ans,minn[y][i]); 105 x=f[x][i]; 106 y=f[y][i]; 107 } 108 ans=min(ans,minn[x][0]); 109 ans=min(ans,minn[y][0]); 110 if(ans==0x7fffffff||ans==0) 111 ans=-1; 112 return ans; 113 } 114 115 void work() 116 { 117 int q; 118 scanf("%d",&q); 119 int x,y; 120 while(q--) 121 { 122 scanf("%d%d",&x,&y); 123 if(find(x)!=find(y)) 124 printf("-1\n"); 125 else 126 printf("%d\n",lca(x,y)); 127 } 128 } 129 130 int main() 131 { 132 init(); 133 mst(); 134 for(int i=1;i<=n;i++) 135 { 136 if(!v[i]) 137 build(i,1); 138 } 139 work(); 140 return 0; 141 }