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 }

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 }

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 }

时间: 2024-10-12 14:38:49

poj1330|bzoj3732|noip2013 货车运输 kruskal+倍增lca的相关文章

洛谷 P1967 货车运输 Label: 倍增LCA &amp;&amp; 最小瓶颈路

题目描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物. 输入输出格式 输入格式: 输入文件名为 truck.in. 输入文件第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道 路. 接下来 m 行每行 3 个整数 x. y. z,每两个整数之间用一个空格隔开,表示从 x 号城市到 y 号城市有一条限重为 z

NOIP2013 货车运输(最大生成树+LCA)

模拟考试的时候暴搜,结果写丑了,分都不分 下来啃了一下题解,发现要用到一个叫做倍增的东西,还没有学过.但是老师说的,没有那个东西,写暴力也有30~40分... 我觉得最大生成树还是很好理解的,因为我们要求的是图中任意两个点之间的路径上,使得边权的最小值尽量大.因此首先求最大生成树. 当我们得到最大生成树后,要求两个点之间边权最小值,我们可以首先找到他们的公共祖先.这里有一篇写得很详细的代码,并且注明了各种写法的得分http://blog.csdn.net/gengmingrui/article/

BZOJ 3732 Network Kruskal+倍增LCA

题目大意:给定一个n个点m条边的无向连通图,k次询问两点之间所有路径中最长边的最小值 NOIP2013 货车运输,几乎就是原题...只不过最小边最大改成了最大边最小... 首先看到最大值最小第一反应二分答案 但是二分答案O(kmlogn)明显做不了 这里我们考虑最小生成树 先生成一棵最小生成树,然后每次询问利用倍增LCA求出路径上的最大权值即可 本蒟蒻居然把LCA写挂了... 而且样例还过了... 伤不起啊... 90%达成 剩下一道刷点啥呢... #include<cstdio> #incl

倍增LCA NOIP2013 货车运输

货车运输 题目描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物. 输入输出格式 输入格式: 输入文件名为 truck.in. 输入文件第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道 路. 接下来 m 行每行 3 个整数 x. y. z,每两个整数之间用一个空格隔开,表示从 x 号城市到 y 号城市有一条

洛谷T1967 货车运输 Kruskal最大生成树&amp;&amp;倍增LCA

这题的题意是:对于每组x.y,求x到y路径上最小边权的最大值.于是可以使用最大生成树,因为最大生成树满足性质:生成树中最小边权最大,且任意两点间路径上最小边权最大.有了树之后,要求路径,那就要考虑LCA.首先,这题可以树剖,但是我太懒了,于是写了倍增233具体搞法:Kruskal跑出最大生成树,然后在树上倍增LCA,处理出2个数组:fa[][]和minv[][]:fa[][]表示第2^k个父亲是谁,minv[][]表示当前节点到其第2^k个父亲的路径上的最小边权.对于每次查询,在求LCA的同时,

【NOIP2013货车运输】

描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物. 格式 输入格式 第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道路. 接下来 m 行每行 3 个整数 x.y.z,每两个整数之间用一个空格隔开,表示从 x 号城市到 y 号城市有一条限重为 z 的道路.注意:x 不等于 y,两座城市之间可能有多条道路. 接

luogu1967[NOIP2013D1T3] 货车运输 (最大生成树+LCA)

题目描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物. 输入输出格式 输入格式: 输入文件名为 truck.in. 输入文件第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道 路. 接下来 m 行每行 3 个整数 x. y. z,每两个整数之间用一个空格隔开,表示从 x 号城市到 y 号城市有一条限重为 z

Codevs3278[NOIP2013]货车运输

3287 货车运输 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物. 输入描述 Input Description 第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和

noip2013货车运输

P1967 货车运输 题目描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物. 输入输出格式 输入格式: 输入文件名为 truck.in. 输入文件第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道 路. 接下来 m 行每行 3 个整数 x. y. z,每两个整数之间用一个空格隔开,表示从 x 号城市到 y