NOIP2013D1T3货车运输(最大生成树+倍增lca)
传送门
这道题,先用kruskal求一遍图中的最大生成树。
然后,倍增求lca,求lca的同时求出边权的最小值。
#include <cstring> #include <cstdio> #include <algorithm>int n, m, cnt, q, t, k; int f[10001], head[100001], p[10001][21], minn[10001][21], deep[10001]; bool vis[10001]; struct node {int x, y, z; }tree[100001]; struct Node {int next, to, val; }edge[100001];inline void add(int a, int b, int c) {edge[cnt].val = c;edge[cnt].to = b;edge[cnt].next = head[a];head[a] = cnt++; }inline int father(int a) {return a == f[a] ? a : f[a] = father(f[a]); }inline bool cmp(node a, node b) {return a.z > b.z; }void kruskal() {int i;for(i = 1; i <= m; i++) scanf("%d %d %d", &tree[i].x, &tree[i].y, &tree[i].z);for(i = 1; i <= n; i++) f[i] = i;std::sort(tree + 1, tree + m + 1, cmp);for(i = 1; i <= m; i++){int fa = father(tree[i].x), fb = father(tree[i].y);if(fa != fb){f[fa] = fb;add(tree[i].x, tree[i].y, tree[i].z);add(tree[i].y, tree[i].x, tree[i].z);}if(k == n - 1) break;} }void dfs(int i) {int j;vis[i] = 1;for(j = head[i]; j != -1; j = edge[j].next)if(!vis[edge[j].to]){deep[edge[j].to] = deep[i] + 1;p[edge[j].to][0] = i;minn[edge[j].to][0] = edge[j].val;dfs(edge[j].to);} }void init() {int i, j;for(j = 1; (1 << j) <= n; j++)for(i = 1; i <= n; i++){p[i][j] = p[p[i][j - 1]][j - 1];minn[i][j] = std::min(minn[i][j - 1], minn[p[i][j - 1]][j - 1]);} }int lca(int a, int b) {int i, j, ret = 707406378;if(deep[a] < deep[b]) std::swap(a, b);for(i = 0; (1 << i) <= deep[a]; i++);i--;for(j = i; j >= 0; j--)if(deep[a] - (1 << j) >= deep[b]){ret = std::min(ret, minn[a][j]);a = p[a][j];}if(a == b) return ret;for(j = i; j >= 0; j--)if(p[a][j] != p[b][j]){ret = std::min(ret, std::min(minn[a][j], minn[b][j]));a = p[a][j];b = p[b][j];}ret = std::min(ret, std::min(minn[a][0], minn[b][0]));return ret; }int main() {int i, j, x1, y1;scanf("%d %d", &n, &m);memset(head, -1, sizeof(head));//memset(minn, 127 / 3, sizeof(minn)); kruskal();for(i = 1; i <= n; i++)if(!vis[i]){deep[i] = 1;dfs(i);}init();scanf("%d", &q);for(i = 1; i <= q; i++){scanf("%d %d", &x1, &y1);if(father(x1) != father(y1)) printf("-1\n");else printf("%d\n", lca(x1, y1));}return 0;}
View Code
换了写法
惨啊,
i >= 0 我居然nc的用 i 代替
应该是 i >= 1 用 i 代替
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 const int MAXN = 10001, MAXM = 50001, INF = 707406378; 6 int n, m, q, cnt, tot; 7 int head[MAXM], to[MAXM << 1], next[MAXM << 1], val[MAXM << 1]; 8 int f1[MAXN], f[MAXN][21], min[MAXN][21], deep[MAXN]; 9 10 struct node 11 { 12 int x, y, z; 13 }p[MAXM]; 14 15 inline bool cmp(node a, node b) 16 { 17 return a.z > b.z; 18 } 19 20 inline void add(int x, int y, int z) 21 { 22 to[cnt] = y; 23 val[cnt] = z; 24 next[cnt] = head[x]; 25 head[x] = cnt++; 26 } 27 28 inline int find(int x) 29 { 30 return x == f1[x] ? x : f1[x] = find(f1[x]); 31 } 32 33 inline int Min(int x, int y) 34 { 35 return x < y ? x : y; 36 } 37 38 inline void swap(int &x, int &y) 39 { 40 x ^= y ^= x ^= y; 41 } 42 43 inline void dfs(int u) 44 { 45 int i, v; 46 deep[u] = deep[f[u][0]] + 1; 47 for(i = 0; f[u][i]; i++) 48 f[u][i + 1] = f[f[u][i]][i], 49 min[u][i + 1] = Min(min[u][i], min[f[u][i]][i]); 50 for(i = head[u]; i ^ -1; i = next[i]) 51 { 52 v = to[i]; 53 if(!deep[v]) 54 { 55 f[v][0] = u; 56 min[v][0] = val[i]; 57 dfs(v); 58 } 59 } 60 } 61 62 inline int lca(int x, int y) 63 { 64 int i, ans = INF; 65 if(deep[x] < deep[y]) swap(x, y); 66 for(i = 20; i >= 0; i--) 67 if(deep[f[x][i]] >= deep[y]) 68 ans = Min(ans, min[x][i]), x = f[x][i]; 69 if(x == y) return ans == INF ? -1 : ans; 70 for(i = 20; i >= 0; i--) 71 if(f[x][i] ^ f[y][i]) 72 ans = Min(ans, min[x][i]), 73 ans = Min(ans, min[y][i]), 74 x = f[x][i], y = f[y][i]; 75 ans = Min(ans, min[x][0]); 76 ans = Min(ans, min[y][0]); 77 return ans == INF ? -1 : ans; 78 } 79 80 int main() 81 { 82 //freopen("truck.in", "r", stdin); 83 //freopen("truck.out", "w", stdout); 84 int i, x, y, fx, fy; 85 scanf("%d %d", &n, &m); 86 memset(head, -1, sizeof(head)); 87 memset(min, 127 / 3, sizeof(min)); 88 for(i = 1; i <= m; i++) scanf("%d %d %d", &p[i].x, &p[i].y, &p[i].z); 89 std::sort(p + 1, p + m + 1, cmp); 90 for(i = 1; i <= n; i++) f1[i] = i; 91 for(i = 1; i <= m; i++) 92 { 93 fx = find(p[i].x); 94 fy = find(p[i].y); 95 if(fx ^ fy) 96 { 97 f1[fx] = fy; 98 tot++; 99 add(p[i].x, p[i].y, p[i].z); 100 add(p[i].y, p[i].x, p[i].z); 101 } 102 if(tot == n - 1) break; 103 } 104 for(i = 1; i <= n; i++) 105 if(!deep[i]) 106 dfs(i); 107 scanf("%d", &q); 108 for(i = 1; i <= q; i++) 109 { 110 scanf("%d %d", &x, &y); 111 if(find(x) ^ find(y)) puts("-1"); 112 else printf("%d\n", lca(x, y)); 113 } 114 return 0; 115 }
View Code
转载于:https://www.cnblogs.com/zhenghaotian/p/6667614.html
NOIP2013D1T3货车运输(最大生成树+倍增lca)相关推荐
- poj1330|bzoj3732|noip2013 货车运输 kruskal+倍增lca
学了一早上倍增,感觉lca还是tarjan好写. poj1330 1 #include <stdio.h> 2 #include <string.h> 3 #include & ...
- 洛谷T1967 货车运输 Kruskal最大生成树倍增LCA
这题的题意是:对于每组x.y,求x到y路径上最小边权的最大值. 于是可以使用最大生成树,因为最大生成树满足性质:生成树中最小边权最大,且任意两点间路径上最小边权最大. 有了树之后,要求路径,那就要考虑 ...
- 洛谷1967 火车运输 kruskal求最大生成树 倍增LCA维护最小值
传送门 其实NOIP某些年的第三题也并不是很难嘛... 题目分析: 题目中要求求出某两点之间可以运输的最大重量,也就是这两个点的某条路径上边权最小的边的权值的最大值 很显然,题目中的运输最大重量与选择 ...
- CodeVS3287[NOIP2013] 货车运输【Kruskal+倍增求LCA】
题目描述 Description A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过 ...
- P1967 货车运输( 最大生成树+LCA or Kruskal重构树)
至于为什么要用最大生成树!? 理由:因为问最大载重,如果要加大载重的话,对于选择的路肯定权重越大越好,所以贪心地想,得用到最大生成树.然后两点之间的最大载重用LCA去寻找就可以了. 最大生成树+LCA ...
- P1967,ssl2267-货车运输【树上倍增LCA,最小生成树变形kruskal】
正题 题目链接: https://www.luogu.org/problemnew/show/P1967 大意 一个无向图,每个边有个权值,若干个询问,求两个点之间的一条最短路是这条最短路上的最小权值 ...
- NOIP2013 D1T3 货车运输 倍增LCA OR 并查集按秩合并
思路: Kruskal求最大生成树+倍增LCA // by SiriusRen #include <cstdio> #include <cstring> #include &l ...
- 洛古1967 货车运输
具体思路: 最大生成树 + 倍增LCA 首先感谢tqc大佬为我的耐心修改代码(你可能是改了个shi- -) 贴代码 include include include include include us ...
- 货车运输题解 最大生成树+lca
3287 货车运输 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目描述 Description A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条 ...
最新文章
- Python 报错解决:AttributeError: 'module' object has no attribute 'SSL_ST_INIT'
- Win10 安装msi 提示2502、2503的错误代码 -- 命令提示符(管理员) -- msiexec /package...
- 哪些医药企业使用SAP系统呢?
- 数据结构:试设计一个算法,改造一个带表头结点的双向链表,所有结点的原有次序保持在各个结点的右链域rLink中,并利用左链域ILink把所有结点按照其值从小到大的顺序连接起来
- RabbitMQ入门(二)-helloworld
- 理解快速生成树协议(RSTP)(二)
- pytorch学习笔记(十七):Read-Write
- java web应用程序_说说Java Web中的Web应用程序|乐字节
- XDeepFM高阶特征交互,特征交互:一种极深因子分解机模型
- HBase的两种协处理器
- Android源码:1、如何下载源码详解(一)
- 基于朴素贝叶斯的新闻分类
- [Luogu P3164] [BZOJ 3503] [CQOI2014]和谐矩阵
- latex设置times new roman新罗马字体
- msp430开发环境安装
- leetcode 717. 1比特与2比特字符(python)
- dnfdpl服务器维护了,2019DNF心悦DPL活动地址 DNF心悦DPL活动网址及奖励一览
- TextView实现水平滚动
- jenkins 403 No valid crumb was included in the request 解决方案
- 贝壳金服 TiDB 在线跨机房迁移实践
热门文章
- 图论算法 最短路程_从网页排序看图论的重要应用
- 与c++ 进行最简单的进程通信
- fetch ajax cros,由 Fetch 跨域 看 CORS
- pytorch cpu版本安装_pytorch深度学习框架--gpu和cpu的选择
- [大学回忆录]尧山学习生活总结
- u-boot移植随笔:System.map文件格式
- 【nexus】nexus 仓库组的概念 以及相关配置 代码发布相关
- 【Elasticsearch】es Timelion是Kibana中时间序列的可视化工具
- 【Elasticsearch】ES Elasticsearch查询优化
- 【Java】Java 集合相关的博客积累