题意:给一棵边带权的树
有m个询问x,y 询问x到y的路径上的最长边和最短边
思路:离线做
用tarjan求LCA
每次合并时,只把儿子往根上合并 保证并查集的某一节点的祖先也都是这个节点在树上的祖先
并查集每个节点再维护一个与父亲节点的路径上的最长边和最短边
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 #include<vector> 6 #include<algorithm> 7 using namespace std; 8 #define MAXN 100001 9 struct node 10 { 11 int num,weight; 12 node *next; 13 }; 14 node *graph[MAXN]; 15 int f[MAXN]; 16 int father[MAXN]; 17 pair<int,int> edge[MAXN]; 18 pair<int,int> a[MAXN]; 19 pair<int,int> ans[MAXN]; 20 vector<pair<int,int> > query[MAXN]; 21 vector<int> b[MAXN]; 22 node memo[2*MAXN]; 23 bool use[MAXN]; 24 int top; 25 int n,m; 26 int root; 27 int x1,x2; 28 void add(int x,int y,int w) 29 { 30 node *p=&memo[top++]; 31 p->num=y; p->next=graph[x]; p->weight=w; graph[x]=p; 32 p=&memo[top++]; 33 p->num=x; p->next=graph[y]; p->weight=w; graph[y]=p; 34 } 35 int find(int x) 36 { 37 if(f[x]==-1) return x; 38 int root=find(f[x]); 39 edge[x].first=max(edge[x].first,edge[f[x]].first); 40 edge[x].second=min(edge[x].second,edge[f[x]].second); 41 f[x]=root; 42 return root; 43 } 44 void merge(int x,int y) 45 { 46 if(find(x)!=find(y)) 47 f[find(x)]=find(y); 48 } 49 void LCA(int u) 50 { 51 edge[u].first=0; edge[u].second=987654321; 52 for(node *p=graph[u];p;p=p->next) 53 if(p->num!=father[u]) 54 { 55 father[p->num]=u; 56 LCA(p->num); 57 edge[p->num].first=edge[p->num].second=p->weight; 58 merge(p->num,u); 59 } 60 use[u]=1; 61 vector<pair<int,int> >:: iterator i; 62 int j; 63 for(i=query[u].begin();i!=query[u].end();i++) 64 if(use[i->first]) 65 b[find(i->first)].push_back(i->second); 66 for(j=0;j<b[u].size();j++) 67 { 68 find(a[b[u][j]].first); find(a[b[u][j]].second); 69 ans[b[u][j]]=make_pair(max(edge[a[b[u][j]].first].first,edge[a[b[u][j]].second].first),min(edge[a[b[u][j]].first].second,edge[a[b[u][j]].second].second)); 70 } 71 72 } 73 int main() 74 { 75 memset(graph,0,sizeof(graph)); 76 memset(use,0,sizeof(use)); 77 memset(f,0xff,sizeof(f)); 78 int i; 79 int x,y,z; 80 scanf("%d",&n); 81 top=0; 82 for(i=1;i<n;i++) 83 { 84 scanf("%d%d%d",&x,&y,&z); 85 add(x,y,z); 86 } 87 scanf("%d",&m); 88 memset(use,0,sizeof(use)); 89 for(i=1;i<=m;i++) 90 { 91 scanf("%d%d",&a[i].first,&a[i].second); 92 query[a[i].first].push_back(make_pair(a[i].second,i)); 93 query[a[i].second].push_back(make_pair(a[i].first,i)); 94 } 95 father[1]=0; 96 LCA(1); 97 for(i=1;i<=m;i++) 98 printf("%d %d\n",ans[i].second,ans[i].first); 99 return 0; 100 } 101 102 103