【题目链接】

 

    http://www.lydsy.com/JudgeOnline/problem.php?id=3732

 

【题意】

 

    给定一个无向图,处理若干询问:uv路径上最长的边最小是多少?

 

【思路一】

 

    最小生成树+倍增算法。

    同NOIP2013货车运输。

 

【代码】

 

  1 #include<set>
  2 #include<cmath>
  3 #include<queue>
  4 #include<vector>
  5 #include<cstdio>
  6 #include<cstring>
  7 #include<iostream>
  8 #include<algorithm>
  9 #define trav(u,i) for(int i=front[u];i;i=e[i].nxt)
 10 #define FOR(a,b,c) for(int a=(b);a<=(c);a++)
 11 using namespace std;
 12 
 13 typedef long long ll;
 14 const int N = 1e5+10;
 15 const int M = 2e5+10;
 16 const int D = 21;
 17 const int inf = 2e9;
 18 
 19 ll read() {
 20     char c=getchar();
 21     ll f=1,x=0;
 22     while(!isdigit(c)) {
 23         if(c=='-') f=-1; c=getchar();
 24     }
 25     while(isdigit(c))
 26         x=x*10+c-'0',c=getchar();
 27     return x*f;
 28 }
 29 
 30 struct Edge { 
 31     int u,v,w,nxt;
 32     bool operator < (const Edge& rhs) const{
 33         return w<rhs.w;
 34     }
 35 }e[M];
 36 int en=1,front[N];
 37 void adde(int u,int v,int w) 
 38 {
 39     e[++en]=(Edge){u,v,w,front[u]}; front[u]=en;
 40 }
 41 vector<Edge> es;
 42 
 43 int n,m,K,p[N],_max[N][D],fa[N][D],dep[N];
 44 
 45 int ifind(int u)
 46 {
 47     return u==p[u]? u:p[u]=ifind(p[u]);
 48 }
 49 
 50 void Kruskal()
 51 {
 52     sort(es.begin(),es.end());
 53     FOR(i,0,(int)es.size()-1) {
 54         int u=es[i].u,v=es[i].v,w=es[i].w;
 55         int x=ifind(u),y=ifind(v);
 56         if(x!=y) {
 57             p[x]=y;
 58             adde(u,v,w); adde(v,u,w);
 59         }
 60     }
 61 }
 62 void dfs(int u,int father)
 63 {
 64     trav(u,i) {
 65         int v=e[i].v;
 66         if(v!=father) {
 67             fa[v][0]=u;
 68             _max[v][0]=e[i].w;
 69             dep[v]=dep[u]+1;
 70             FOR(j,1,D-1) {
 71                 fa[v][j]=fa[fa[v][j-1]][j-1];
 72                 _max[v][j]=max(_max[v][j-1],_max[fa[v][j-1]][j-1]);
 73             }
 74             dfs(v,u);
 75         }
 76     }
 77 }
 78 
 79 int query(int u,int v)
 80 {
 81     if(dep[u]<dep[v]) swap(u,v);
 82     int t=dep[u]-dep[v],ans=-inf;
 83     FOR(i,0,D-1)
 84         if(t&(1<<i)) {
 85             ans=max(ans,_max[u][i]);
 86             u=fa[u][i];
 87         }
 88     if(u==v) return ans;
 89     for(int i=D-1;i>=0;i--)
 90         if(fa[u][i]!=fa[v][i]) {
 91             ans=max(ans,max(_max[u][i],_max[v][i]));
 92             u=fa[u][i],v=fa[v][i];
 93         }
 94     ans=max(ans,max(_max[u][0],_max[v][0]));
 95     return ans;
 96 }
 97 
 98 int main()
 99 {
100     n=read(),m=read(),K=read();
101     FOR(i,0,n) FOR(j,0,D-1) _max[i][j]=-inf;
102     FOR(i,1,n) p[i]=i;
103     FOR(i,1,m) {
104         int u=read(),v=read(),w=read();
105         es.push_back((Edge){u,v,w,0});
106     }
107     Kruskal();
108     dfs(1,-1);
109     FOR(i,1,K) {
110         int u=read(),v=read();
111         printf("%d\n",query(u,v));
112     }
113     return 0;
114 }
View Code

相关文章: