bzoj3732: Network

最小生成树的性质 任意两点间最大边最小

不会写倍增系列= =

 1 #include<bits/stdc++.h>
 2 #define rep(i,l,r) for(int i=l;i<=r;++i)
 3 using namespace std;
 4 const int N=102333;
 5 int tot,dep[N],sz[N],f[N],fa[N][25],s[N][25],x,y,a,b,c,n,m,K,now,mn,top[N],son[N],head[N],cnt;
 6 struct Edge{
 7     int to,next,w;
 8 }e[N];
 9 struct zs{
10     int a,b,c;
11 }e1[N];
12 int find(int x){
13     return f[x]==x?x:f[x]=find(f[x]);
14 }
15 bool cmp(zs a,zs b){
16     return a.c<b.c;
17 }
18 inline void ins(int u,int v,int w){
19     e[++tot].to=v; e[tot].next=head[u]; head[u]=tot; e[tot].w=w;
20 }
21 inline void dfs1(int x,int pre) {
22      dep[x]=dep[pre]+1;
23      for(int k=head[x];k;k=e[k].next) {
24           if(e[k].to==pre)  continue;
25           fa[e[k].to][0]=x;
26           s[e[k].to][0]=e[k].w;
27           dfs1(e[k].to,x);
28      }
29 }
30 inline int work(int x,int y){
31     int mx=0;
32     if(dep[x]<dep[y]) swap(x,y);
33     for(int j=20;j>=0;--j) 
34         if(fa[x][j]&&dep[fa[x][j]]>=dep[y]) mx=max(mx,s[x][j]),x=fa[x][j];
35     if(x==y)return mx;
36     for(int j=20;j>=0;--j) if(fa[x][j]&&fa[y][j]&&fa[x][j]!=fa[y][j]){
37         mx=max(mx,s[x][j]); mx=max(mx,s[y][j]);
38         x=fa[x][j]; y=fa[y][j];
39     }
40     mx=max(mx,max(s[x][0],s[y][0]));
41     return mx;
42 }
43 int main(){
44     scanf("%d%d%d",&n,&m,&K);
45     rep(i,1,m)scanf("%d%d%d",&e1[i].a,&e1[i].b,&e1[i].c);
46     sort(e1+1,e1+1+m,cmp);
47     rep(i,1,n)f[i]=i;
48     rep(i,1,m){
49         x=find(e1[i].a); y=find(e1[i].b); c=e1[i].c;
50         if(x!=y){
51             f[x]=y;
52             ins(e1[i].a,e1[i].b,c);
53             ins(e1[i].b,e1[i].a,c);
54         }
55     }
56     dfs1(1,0);
57     rep(j,1,20) rep(x,1,n)fa[x][j]=fa[fa[x][j-1]][j-1],s[x][j]=max(s[x][j-1],s[fa[x][j-1]][j-1]);
58     while(K--){
59         scanf("%d%d",&a,&b); 
60         printf("%d\n",work(a,b));
61     }
62 }
View Code

 

posted @ 2016-11-05 16:35  Bloodline  阅读(154)  评论(0编辑  收藏  举报