poj1330|bzoj3732|noip2013 货车运输 kruskal+倍增lca

学了一早上倍增,感觉lca还是tarjan好写。

poj1330

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <queue>
 4 #include <algorithm>
 5 #define DEG 20//2^20
 6 #define maxn 10010
 7 using namespace std;
 8 struct node 
 9 {
10     int v, next;
11 }a[maxn*2];
12 int q[4*maxn], fa[maxn][DEG], root, n, m, u, v, tot, first[maxn*2], dis[maxn];
13 bool flag[maxn];
14 void addedge(int st, int end)
15 {
16     a[tot].v = end;
17     a[tot].next = first[st]; first[st] = tot++;
18 }
19 void init()
20 {
21     tot = 0;
22     memset(first, -1, sizeof(first));
23     memset(flag, 0, sizeof(flag));
24 }
25 void bfs(int root)
26 {
27     queue<int >que;
28     dis[root] = 0;
29     fa[root][0] = root;//root's 2^0 father is root
30     que.push(root);
31     //q[0] = root;
32     //int head = 0,tail = 1;
33     while (!que.empty())
34     {
35         //int u = q[head++];
36         int u = que.front();que.pop();
37         for (int i = 1; i < DEG; i++)/*the father from 2^1 ~ 2^DEG*/fa[u][i] = fa[fa[u][i-1]][i-1];//u's 2^i father is u's (2^(i-1))^(i-1)
38         for (int e = first[u]; e != -1; e = a[e].next)
39         {
40             int v = a[e].v;
41             if (v == fa[u][0])continue;//if u's father is v,continue, it can't vis his fahter
42             dis[v] = dis[u] + 1;
43             fa[v][0] = u;
44             //q[++tail] = v;
45             que.push(v);
46         }
47     }
48 }
49 int LCA(int u, int v)
50 {
51     if (dis[u] > dis[v])swap(u, v);
52     int du = dis[u], dv = dis[v];
53     int tu = u, tv = v;
54     for (int det = dv - du, i = 0;det; det>>=1, i++)
55         if (det&1)//det if u's high - v's high;
56         tv = fa[tv][i];//let deeper point up(2^i) until det = 1;
57     if (tu == tv)return tu;
58     for (int i = DEG - 1; i >= 0; i--)
59     {
60         if (fa[tu][i] == fa[tv][i])continue;
61         tu = fa[tu][i];
62         tv = fa[tv][i];
63     }
64     return fa[tu][0];
65 }
66 int main()
67 {
68     int T;
69     scanf("%d", &T);
70     while (T--)
71     {
72         scanf("%d", &n);
73         init();
74         for (int i = 1; i < n; i++)
75         {
76             scanf("%d %d", &u, &v);
77             addedge(u, v);addedge(v, u);
78             flag[v] = 1;
79         }
80         int root;
81         for (int i = 1; i <= n; i++)
82         {
83             if (!flag[i])
84             {
85                 root =  i;break;
86             }
87         }
88         bfs(root);//dfs(root);
89         scanf("%d %d", &u, &v);
90         printf("%d\n", LCA(u,v));
91     }
92 }
View Code

bzoj3732

 1 /**************************************************************
 2     Problem: 3732
 3     User: z52527
 4     Language: C++
 5     Result: Accepted
 6     Time:392 ms
 7     Memory:7304 kb
 8 ****************************************************************/
 9  
10 #include <stdio.h>
11 #include <string.h>
12 #include <algorithm>
13 #define DEG 20//2^20
14 #define maxn 30010
15 using namespace std;
16 struct node 
17 {
18     int u, v, w, next;
19 }a[maxn], b[maxn];
20 int first[maxn], m, n, q, tot;
21 int dis[maxn], fa[maxn][DEG], maxf[maxn][DEG], ans, father[maxn];
22 void addedge(int st, int end, int val)
23 {
24     b[++tot].u = st;b[tot].v = end;b[tot].w = val;
25     b[tot].next = first[st]; first[st] = tot;
26 }
27 int getfather(int x){return father[x] == x ? x : getfather(father[x]);}
28 int cmp (node a, node b){return a.w < b.w;}
29 int dfs(int u)
30 {
31     dis[u] = dis[fa[u][0]]+1;
32     for (int e = first[u]; e != -1; e = b[e].next)
33     {
34             if (b[e].v == fa[u][0]) continue;
35             fa[b[e].v][0] = u;
36             maxf[b[e].v][0] = b[e].w;
37             dfs(b[e].v);
38     }
39 }
40 int lca(int u, int v)
41 {
42     ans = 0;
43     if (dis[u] > dis[v])swap(u, v);
44     int du = dis[u], dv = dis[v];
45     int fu = u, fv = v;
46     for (int def = dv - du, i = 0; def; def>>=1, i++)
47         if (def&1)
48            ans = max(ans, maxf[fv][i]), fv = fa[fv][i];
49     if (fu == fv)return ans;
50     for (int i = 14; i >=0; i--)
51     {
52         if (fa[fu][i] == fa[fv][i])continue;
53         ans = max(maxf[fu][i], ans);
54         ans = max(maxf[fv][i], ans);   
55         fu = fa[fu][i];
56         fv = fa[fv][i];
57     }
58     ans = max(maxf[fu][0], ans);
59     ans = max(maxf[fv][0], ans);    
60     return ans;
61 }
62 int main()
63 {
64     int u, v, w;
65     scanf("%d %d %d", &n, &m, &q);
66     for (int i = 1; i <= n; i++)father[i] = i;
67     memset(first, -1, sizeof(first));
68     for (int i = 1; i <= m; i++)
69     {
70         scanf("%d %d %d", &u, &v, &w);
71         a[i].u = u;a[i].v = v;a[i].w = w;
72     }
73     sort(a+1, a+1+m, cmp);
74     for (int i = 1; i <= m; i++)
75     {
76         u = getfather(a[i].u);
77         v = getfather(a[i].v);
78         if (u != v)
79         {
80             father[u] = v;
81             addedge(a[i].u, a[i].v, a[i].w);
82             addedge(a[i].v, a[i].u, a[i].w);
83         }
84     }
85     dfs(1);
86     //scanf("%d", &q);
87     for(int j = 1;j <= 14; j++)
88         for(int i = 1;i <= n; i++)
89             fa[i][j] = fa[ fa[i][j-1] ][j-1],maxf[i][j]=max( maxf[i][j-1] , maxf[ fa[i][j-1] ][j-1] );
90     for (int i = 1; i <= q; i++)
91     {
92         scanf("%d %d", &u, &v);
93         printf("%d\n", lca(u, v));
94     }
95 }
View Code

noip2013 货车运输

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <algorithm>
 4 #define DEG 20//2^20
 5 #define maxn 50010
 6 using namespace std;
 7 struct node 
 8 {
 9     int u, v, w, next;
10 }a[maxn], b[maxn];
11 int first[maxn], m, n, q, tot;
12 int dis[maxn], fa[maxn][DEG], maxf[maxn][DEG], ans, father[maxn];
13 void addedge(int st, int end, int val)
14 {
15     b[++tot].u = st;b[tot].v = end;b[tot].w = val;
16     b[tot].next = first[st]; first[st] = tot;
17 }
18 int getfather(int x){return father[x] == x ? x : getfather(father[x]);}
19 int cmp (node a, node b){return a.w > b.w;}
20 int dfs(int u)
21 {
22     dis[u] = dis[fa[u][0]]+1;
23     for (int e = first[u]; e != -1; e = b[e].next)
24     {
25             if (b[e].v == fa[u][0]) continue;
26             fa[b[e].v][0] = u;
27             maxf[b[e].v][0] = b[e].w;
28             dfs(b[e].v);
29     }
30 }
31 int lca(int u, int v)
32 {
33     ans = 2000000000;
34     if (dis[u] > dis[v])swap(u, v);
35     int du = dis[u], dv = dis[v];
36     int fu = u, fv = v;
37     for (int def = dv - du, i = 0; def; def>>=1, i++)
38         if (def&1)
39            ans = min(ans, maxf[fv][i]), fv = fa[fv][i];
40     if (fu == fv)return ans;
41     for (int i = 16; i >= 0; i--)
42     {
43         if (fa[fu][i] == fa[fv][i])continue;
44         ans = min(maxf[fu][i], ans);
45         ans = min(maxf[fv][i], ans);   
46         fu = fa[fu][i];
47         fv = fa[fv][i];
48     }
49     ans = min(maxf[fu][0], ans);
50     ans = min(maxf[fv][0], ans);    
51     return ans;
52 }
53 int main()
54 {
55     int u, v, w;
56     scanf("%d %d", &n, &m);
57     for (int i = 1; i <= n; i++)father[i] = i;
58     memset(first, -1, sizeof(first));
59     for (int i = 1; i <= m; i++)
60     {
61         scanf("%d %d %d", &u, &v, &w);
62         a[i].u = u;a[i].v = v;a[i].w = w;
63     }
64     sort(a+1, a+1+m, cmp);
65     for (int i = 1; i <= m; i++)
66     {
67         u = getfather(a[i].u);
68         v = getfather(a[i].v);
69         if (u != v)
70         {
71             father[u] = v;
72             addedge(a[i].u, a[i].v, a[i].w);
73             addedge(a[i].v, a[i].u, a[i].w);
74         }
75     }
76     dfs(1);
77     scanf("%d", &q);
78     for(int j = 1;j <= 16; j++)
79         for(int i = 1;i <= n; i++)
80             fa[i][j] = fa[ fa[i][j-1] ][j-1],maxf[i][j]=min( maxf[i][j-1] , maxf[ fa[i][j-1] ][j-1] );
81     for (int i = 1; i <= q; i++)
82     {
83         scanf("%d %d", &u, &v);
84         if (getfather(u) != getfather(v)){printf("-1\n");continue;}
85         printf("%d\n", lca(u, v));
86     }
87 }
View Code

 

转载于:https://www.cnblogs.com/z52527/p/4730967.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值