Poj--3728(LCA,修改tarjan)

2014-10-28 13:37:43

思路:LCA好题。尚认为自己没有实力写出题解,和大牛讨论下再写吧。

  1 /*************************************************************************
  2     > File Name: 3728.cpp
  3     > Author: Nature
  4     > Mail: 564374850@qq.com
  5     > Created Time: Sun 26 Oct 2014 04:23:07 PM CST
  6 ************************************************************************/
  7 
  8 #include <cstdio>
  9 #include <cstring>
 10 #include <cstdlib>
 11 #include <cmath>
 12 #include <vector>
 13 #include <map>
 14 #include <set>
 15 #include <stack>
 16 #include <queue>
 17 #include <iostream>
 18 #include <algorithm>
 19 using namespace std;
 20 #define lp (p << 1)
 21 #define rp (p << 1|1)
 22 #define getmid(l,r) (l + (r - l) / 2)
 23 #define MP(a,b) make_pair(a,b)
 24 typedef long long ll;
 25 const int INF = 1 << 30;
 26 const int maxn = 100010;
 27 
 28 int N,Q;
 29 int w[maxn],qa[maxn],qb[maxn];
 30 int first[maxn],next[maxn],ver[maxn],ecnt;
 31 int f1[maxn],n1[maxn],v1[maxn],id1[maxn],e1;
 32 int fa[maxn],vis[maxn],tmin[maxn],tmax[maxn],st[maxn],ed[maxn];
 33 int ans[maxn];
 34 vector<int> g[maxn];
 35 
 36 void Init(){
 37     memset(first,-1,sizeof(first));
 38     memset(f1,-1,sizeof(f1));
 39     for(int i = 1; i <= N; ++i)
 40         g[i].clear();
 41     ecnt = 0;
 42 }
 43 
 44 void Add_edge(int u,int v){
 45     next[++ecnt] = first[u];
 46     ver[ecnt] = v;
 47     first[u] = ecnt;
 48 }
 49 
 50 void Add_edge1(int u,int v,int id){
 51     n1[++e1] = f1[u];
 52     v1[e1] = v;
 53     id1[e1] = id;
 54     f1[u] = e1;
 55 }
 56 
 57 int Find(int x){
 58     return fa[x] == x ? x : Find(fa[x]);
 59 }
 60 
 61 void Union(int u,int v){
 62     int x = Find(u);
 63     int y = Find(v);
 64     if(x != y)
 65         fa[y] = x;
 66 }
 67 
 68 int Update(int x){
 69     if(fa[x] == x)
 70         return x;
 71     int y = fa[x];
 72     fa[x] = Update(fa[x]);
 73     st[x] = max(max(st[y],st[x]),tmax[y] - tmin[x]);
 74     ed[x] = max(max(ed[y],ed[x]),tmax[x] - tmin[y]);
 75     tmax[x] = max(tmax[x],tmax[y]);
 76     tmin[x] = min(tmin[x],tmin[y]);
 77     return fa[x];
 78 }
 79 
 80 void Tarjan(int p,int pre){
 81     fa[p] = p;
 82     vis[p] = 1;
 83     for(int i = f1[p]; ~i; i = n1[i]){
 84         int v = v1[i];
 85         if(vis[v]){
 86             int y = Find(v);
 87             g[y].push_back(id1[i]);
 88         }
 89     }
 90     for(int i = first[p]; ~i; i = next[i]){
 91         int v = ver[i];
 92         if(v != pre){
 93             Tarjan(v,p);
 94             Union(p,v);
 95         }
 96     }
 97     for(int i = 0; i < g[p].size(); ++i){
 98         int id = g[p][i];
 99         int u = qa[id],v = qb[id];
100         Update(u);
101         Update(v);
102         ans[id] = max(max(st[u],ed[v]),tmax[v] - tmin[u]);
103     }
104 }
105 
106 int main(){
107     int a,b;
108     scanf("%d",&N);
109     Init();
110     for(int i = 1; i <= N; ++i){
111         scanf("%d",w + i);
112         tmax[i] = tmin[i] = w[i];
113         st[i] = ed[i] = 0;
114     }
115     for(int i = 1; i < N; ++i){
116         scanf("%d%d",&a,&b);
117         Add_edge(a,b);
118         Add_edge(b,a);
119     }
120     scanf("%d",&Q);
121     for(int i = 1; i <= Q; ++i){
122         scanf("%d%d",&a,&b);
123         qa[i] = a,qb[i] = b;
124         Add_edge1(a,b,i);
125         Add_edge1(b,a,i);
126     }
127     Tarjan(1,0);
128     for(int i = 1; i <= Q; ++i){
129         printf("%d\n",ans[i]);
130     }
131     return 0;
132 }

 

posted @ 2014-10-28 13:38  Naturain  阅读(149)  评论(0编辑  收藏  举报