1. 程式人生 > >lca 例題 WK

lca 例題 WK

clu span fat noip wap esp += log spa

codevs2370 小機房的樹

技術分享
 1 #include<iostream>
 2 #include<cstdio>
 3 #define maxn 110000
 4 using namespace std;
 5 int head[maxn],deep[maxn],sum[maxn][22],f[maxn][22];
 6 int n,m,num,ans;
 7 struct node{
 8     int to,v,pre;
 9 }e[maxn];
10 void Insert(int from,int to,int v){
11     e[++num].to=to;
12 e[num].v=v; 13 e[num].pre=head[from]; 14 head[from]=num; 15 } 16 void find_deep(int from,int now,int dep,int val){ 17 deep[now]=dep;f[now][0]=from;sum[now][0]=val; 18 for(int i=head[now];i;i=e[i].pre){ 19 int v=e[i].to; 20 if(v!=from)find_deep(now,v,dep+1,e[i].v);
21 } 22 } 23 void find_father(){ 24 for(int i=1;i<=21;i++) 25 for(int j=1;j<=n;j++) 26 f[j][i]=f[f[j][i-1]][i-1]; 27 for(int i=1;i<=21;i++) 28 for(int j=1;j<=n;j++) 29 sum[j][i]=sum[f[j][i-1]][i-1]+sum[j][i-1]; 30 } 31 int get(int a,int delta){
32 for(int i=0;i<=21;i++){ 33 if(delta&(1<<i))ans+=sum[a][i],a=f[a][i]; 34 } 35 return a; 36 } 37 int lca(int a,int b){ 38 if(deep[a]<deep[b])swap(a,b); 39 if(a==b)return 0; 40 a=get(a,deep[a]-deep[b]); 41 for(int i=21;i>=0;i--){ 42 if(f[a][i]!=f[b][i]){ 43 ans+=sum[a][i]+sum[b][i]; 44 a=f[a][i];b=f[b][i]; 45 } 46 } 47 if(a!=b)ans+=sum[a][0]+sum[b][0]; 48 } 49 int main(){ 50 scanf("%d",&n); 51 int x,y,z; 52 for(int i=1;i<n;i++){ 53 scanf("%d%d%d",&x,&y,&z); 54 Insert(x+1,y+1,z); 55 Insert(y+1,x+1,z); 56 } 57 find_deep(1,1,0,0); 58 find_father(); 59 scanf("%d",&m); 60 for(int i=1;i<=m;i++){ 61 scanf("%d%d",&x,&y); 62 ans=0;lca(x+1,y+1); 63 printf("%d\n",ans); 64 } 65 }
View Code

cogs1439. [NOIP2013]貨車運輸

技術分享
 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<algorithm>
 6 using namespace std;
 7 #define maxn 10010
 8 #define maxm 50010
 9 int n,m,f[maxn][20],sum[maxn][20],fa[maxn],num,p,dep[maxn],head[maxn]; 
10 bool vis[maxn];
11 struct node{
12     int f,to,v;
13 }a[maxm];
14 struct Edge{
15     int pre,v,to;
16 }e[maxm];
17 int cmp(node x,node y){return x.v>y.v;}
18 int find(int x){
19     if(fa[x]==x)return fa[x];
20     else return fa[x]=find(fa[x]);
21 }
22 int connect(int x,int y){
23     int f1=find(x),f2=find(y);
24     if(f1==f2)return 0;
25     else fa[f1]=f2;return 1;
26 }
27 void Insert(int from,int to,int v){
28     e[++num].v=v;
29     e[num].to=to;
30     e[num].pre=head[from];
31     head[from]=num;
32 }
33 void dfs(int now,int father,int deep){
34     vis[now]=1;
35     dep[now]=deep;
36     for(int i=head[now];i;i=e[i].pre){
37         int v=e[i].to;
38         if(v==father)continue;
39         f[v][0]=now;
40         sum[v][0]=e[i].v;
41         dfs(v,now,deep+1);
42     }
43 }
44 int lca(int x,int y){
45     if(x==y)return 0;
46     int ans=0x3f3f3f3f;
47     if(dep[x]<dep[y])swap(x,y);
48     for(int i=18;i>=0;i--){
49         if(dep[f[x][i]]>=dep[y]&&f[x][i]!=0)ans=min(ans,sum[x][i]),x=f[x][i];
50     }
51     if(x==y)return ans;
52     for(int i=18;i>=0;i--){
53         if(f[x][i]!=f[y][i]){
54             ans=min(ans,sum[x][i]);
55             ans=min(ans,sum[y][i]);
56             x=f[x][i];y=f[y][i];
57         }
58     }
59     ans=min(sum[x][0],ans);ans=min(sum[y][0],ans);
60     return ans;
61 }
62 int main(){
63     //freopen("Cola.txt","r",stdin);
64     freopen("truck.in","r",stdin);
65     freopen("truck.out","w",stdout);
66     memset(sum,127/3,sizeof(sum));
67     int x,y,z;
68     scanf("%d%d",&n,&m);
69     for(int i=1;i<=m;i++)scanf("%d%d%d",&a[i].f,&a[i].to,&a[i].v);
70     for(int i=1;i<=n;i++)fa[i]=i;
71     sort(a+1,a+m+1,cmp);int cnt=0;
72     for(int i=1;i<=m;i++){
73         if(connect(a[i].f,a[i].to)){
74             Insert(a[i].f,a[i].to,a[i].v);
75             Insert(a[i].to,a[i].f,a[i].v);
76             cnt++;if(cnt==n-1)break;
77         }
78     }
79     for(int i=1;i<=n;i++)if(!vis[i])dfs(i,0,1);
80     for(int j=1;(1<<j)<=n;j++)
81         for(int i=1;i<=n;i++)
82             if(f[f[i][j-1]][j-1]!=0){
83                 f[i][j]=f[f[i][j-1]][j-1];
84                 sum[i][j]=min(sum[i][j-1],sum[f[i][j-1]][j-1]);
85             }
86     scanf("%d",&p);
87     for(int i=1;i<=p;i++){
88         scanf("%d%d",&x,&y);
89         if(find(x)!=find(y)){printf("-1\n");continue;}
90         printf("%d\n",lca(x,y));
91     }
92 }
View Code

hdu2586

技術分享
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <vector>
 5 using namespace std;
 6 vector<int> v[41000];
 7 vector<int> w[41000];
 8 int f[41000][21];//f[i][j]表示i點向上2^j層的祖先 
 9 int sum[41000][21];//g[i][j]表示i點到從i向上2^j層的祖先的距離 
10 int dep[41000];
11 int n,m;
12 void dfs(int pos,int pre,int depth)
13 {
14     dep[pos]=depth;
15     for(int i=0;i<v[pos].size();i++)
16     {
17         int t=v[pos][i];
18         if(t==pre) continue;
19         f[t][0]=pos;
20         sum[t][0]=w[pos][i];
21         dfs(t,pos,depth+1);
22     }
23 }
24 int query(int a,int b)
25 {
26     int Sum=0;
27     if(dep[a]<dep[b]) swap(a,b);//深度較深的點 
28     for(int i=20;i>=0;i--)//找到a在深度dep[b]處的祖先 
29     {
30         if(dep[f[a][i]]>=dep[b])
31         {
32             Sum+=sum[a][i];//a到該祖先的距離 
33             a=f[a][i];
34         }
35     }
36     if(a==b) return Sum;//挪到相同深度後如果在同一點直接return 
37     int x;
38     for(int i=20;i>=0;i--)//否則a和b一起往上跳 
39     {
40         if(f[a][i]!=f[b][i])
41         {
42             Sum+=sum[a][i];
43             a=f[a][i];
44             Sum+=sum[b][i];
45             b=f[b][i];
46         }
47     }
48     return Sum+sum[a][0]+sum[b][0];//最後跳到最近公共祖先的下一層,所以要再加上上一層 
49 }
50 int main()
51 {
52     int T;
53     cin>>T;
54     while(T--)
55     {
56         scanf("%d%d",&n,&m);
57         memset(dep,-1,sizeof(dep));
58         memset(f,0,sizeof(f));
59         memset(sum,0,sizeof(sum));
60         for(int i=0;i<n;i++)//md
61             v[i].clear(),w[i].clear();
62         for(int i=1;i<n;i++)
63         {
64             int x,y,c;
65             cin>>x>>y>>c;
66             v[x].push_back(y);
67             w[x].push_back(c);
68             v[y].push_back(x);
69             w[y].push_back(c);
70         }
71         int xxx=v[1].size();
72         dfs(1,0,1);//dfs處理出每個點的深度,以及各種... 
73     
74         for(int i=1;1<<i<=n;i++)
75             for(int j=1;j<=n;j++)
76                 f[j][i]=f[f[j][i-1]][i-1],
77                 sum[j][i]=sum[f[j][i-1]][i-1]+sum[j][i-1];
78         for(int i=1;i<=m;i++)
79         {
80             int x,y;
81             cin>>x>>y;
82             if(x==y) cout<<"0"<<endl;
83             else cout<<query(x,y)<<endl;
84         }
85     }
86     return 0;
87 }
View Code

洛谷3379

技術分享
 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 #define maxn 500010
 5 int n,m,s,f[maxn][22],deep[maxn],head[maxn],num;
 6 struct node{
 7     int to,pre;
 8 }e[maxn<<1];
 9 int qread(){
10     int x=0,j=1;
11     char ch=getchar();
12     while(ch<0||ch>9){if(ch==-)j=-1;ch=getchar();}
13     while(ch<=9&&ch>=0){x=x*10+ch-0;ch=getchar();}
14     return x*j;
15 }
16 void Insert(int from,int to){
17     e[++num].to=to;
18     e[num].pre=head[from];
19     head[from]=num;
20 }
21 void find_deep(int from,int now,int dep){
22     f[now][0]=from;deep[now]=dep;
23     for(int i=head[now];i;i=e[i].pre){
24         int v=e[i].to;
25         if(v!=from){
26             find_deep(now,v,dep+1);
27         }
28     }
29 }
30 void find_father(){
31     for(int j=1;j<=21;j++)
32         for(int i=1;i<=n;i++)
33             f[i][j]=f[f[i][j-1]][j-1];
34 }
35 int get(int a,int delta){
36     for(int i=0;i<=21;i++){
37         if(delta&(1<<i))a=f[a][i];
38     }return a;
39 }
40 int lca(int a,int b){
41     if(deep[a]<deep[b])swap(a,b);
42     a=get(a,deep[a]-deep[b]);
43     if(a==b) return a;
44     for(int i=21;i>=0;i--){
45         if(f[a][i]!=f[b][i]){
46             a=f[a][i],b=f[b][i];
47         }
48     }
49     return f[a][0];
50 }
51 int main(){
52     n=qread(),m=qread(),s=qread();
53     int x,y;
54     for(int i=1;i<=n-1;i++){
55         x=qread();y=qread();
56         Insert(x,y);
57         Insert(y,x);
58     }
59     find_deep(s,s,0);
60     find_father();
61     for(int i=1;i<=m;i++){
62         x=qread();y=qread();
63         int ans=lca(x,y);
64         printf("%d\n",ans);
65     }
66     return 0;
67 }
View Code

lca 例題 WK