【LCA&倍增】货物运输 @upcexam5909
2018-03-21 11:55
183 查看
时间限制: 1 Sec 内存限制: 128 MB
题目描述
在一片苍茫的大海上,有n座岛屿,岛屿与岛屿之间由桥梁连接,所有的岛屿刚好被桥梁连接成一个树形结构,即共n-1架桥梁,且从任何一座岛屿出发都能到达其他任何一座岛屿。
第i座桥梁有一个承重量wi,表示该桥梁一次性最多通过重量为wi的货物。
现在有m个货物运输路线,第i个路线要从岛屿xi出发到达岛屿yi。为了最大化利益,你需要求出在不超过路线上任何一架桥梁的承重量的基础上,每个路线最多运输重量为多少货物。
输入
第一行为两个整数n,m。
接下来n-1行,每行三个整数x,y,w,表示有一座承重量为w的桥梁连接岛屿x和y。
接下来m行,每行两个整数x,y,表示有一条从岛屿x出发到达岛屿y的路线,保证x≠y。
输出
输出共m行,每行一个整数,第i个整数表示第i条路线的最大重量。
样例输入
6 5
1 2 2
2 3 5
2 4 2
2 5 3
5 6 1
2 4
6 2
1 3
3 5
1 6
样例输出
2
1
2
3
1
提示
岛屿间连接情况如图所示:
2,4间只有一架桥,该路线最大运输重量为2
6,2间有两架桥,承重分别为3和1,该路线最大运输重量为1
剩余询问不再作解释
对于50%的数据n,m<=2000
对于100%的数据 n,m<=100000,w<=10^9
来源
2018山东冬令营
http://exam.upc.edu.cn/problem.php?id=5909
思路
第一次写倍增求LCA
这一题每次查询的两个点 x,y
可以考虑倍增求这两个点的LCA
用g[i][j]表示从i到i的第2^j个祖先的所经过的路的最小权值
维护时 g[i][j]=min( g[i][j-1] , g[ f[i][j-1] ][j-1] )
当x或y向根节点移动时,将对应路径上的最小值与答案取min
代码
题目描述
在一片苍茫的大海上,有n座岛屿,岛屿与岛屿之间由桥梁连接,所有的岛屿刚好被桥梁连接成一个树形结构,即共n-1架桥梁,且从任何一座岛屿出发都能到达其他任何一座岛屿。
第i座桥梁有一个承重量wi,表示该桥梁一次性最多通过重量为wi的货物。
现在有m个货物运输路线,第i个路线要从岛屿xi出发到达岛屿yi。为了最大化利益,你需要求出在不超过路线上任何一架桥梁的承重量的基础上,每个路线最多运输重量为多少货物。
输入
第一行为两个整数n,m。
接下来n-1行,每行三个整数x,y,w,表示有一座承重量为w的桥梁连接岛屿x和y。
接下来m行,每行两个整数x,y,表示有一条从岛屿x出发到达岛屿y的路线,保证x≠y。
输出
输出共m行,每行一个整数,第i个整数表示第i条路线的最大重量。
样例输入
6 5
1 2 2
2 3 5
2 4 2
2 5 3
5 6 1
2 4
6 2
1 3
3 5
1 6
样例输出
2
1
2
3
1
提示
岛屿间连接情况如图所示:
2,4间只有一架桥,该路线最大运输重量为2
6,2间有两架桥,承重分别为3和1,该路线最大运输重量为1
剩余询问不再作解释
对于50%的数据n,m<=2000
对于100%的数据 n,m<=100000,w<=10^9
来源
2018山东冬令营
http://exam.upc.edu.cn/problem.php?id=5909
思路
第一次写倍增求LCA
这一题每次查询的两个点 x,y
可以考虑倍增求这两个点的LCA
用g[i][j]表示从i到i的第2^j个祖先的所经过的路的最小权值
维护时 g[i][j]=min( g[i][j-1] , g[ f[i][j-1] ][j-1] )
当x或y向根节点移动时,将对应路径上的最小值与答案取min
代码
#define FILE() freopen("../../in.txt","r",stdin) #include <bits/stdc++.h> using namespace std; const int maxn = 100005; const int maxl = 20; const int INF = 0x3f3f3f3f; int anc[maxn][maxl],fa[maxn],deep[maxn],n,m,cnt,head[maxn];//anc记录祖先,fa记录父亲节点,deep记录深度 int g[maxn][maxl]; struct edge{ int v,w,nex; }ed[maxn*2]; void addedge(int u,int v,int w){ cnt++; ed[cnt].v = v; ed[cnt].w = w; ed[cnt].nex = head[u]; head[u] = cnt; } void dfs(int x){ anc[x][0] = fa[x]; for(int i=1;i<maxl;i++){ anc[x][i] = anc[anc[x][i-1]][i-1]; g[x][i] = min(g[x][i-1],g[anc[x][i-1]][i-1]); // a491 } for(int i=head[x];i;i=ed[i].nex){ if(ed[i].v!=fa[x]){ int y = ed[i].v; fa[y] = x; deep[y] = deep[x]+1; g[y][0] = ed[i].w; // dfs(y); } } } int lca(int x,int y){ int ret = INF; if(deep[x]<deep[y])swap(x,y); for(int i=maxl-1;i>=0;i--){ if(deep[y]<=deep[anc[x][i]]){ ret = min(ret,g[x][i]); x = anc[x][i]; } } // if(x==y)return x; for(int i=maxl-1;i>=0;i--){ if(anc[x][i]!=anc[y][i]){ ret = min(ret,g[x][i]); ret = min(ret,g[y][i]); x = anc[x][i]; y = anc[y][i]; } } if(x!=y){ ret = min(ret,g[x][0]); ret = min(ret,g[y][0]); } return ret; } int main() { // FILE(); cin>>n>>m; for(int i=0;i<n-1;i++){ int from,to,value; scanf("%d%d%d",&from,&to,&value); addedge(from,to,value); addedge(to,from,value); } for(int i=0;i<n;i++){ for(int j=0;j<maxl;j++){ g[i][j] = INF; } } dfs(1); for(int i=0;i<m;i++){ int x,y; scanf("%d%d",&x,&y); printf("%d\n",lca(x,y)); } return 0; }
相关文章推荐
- 洛谷 P1967 货车运输(Kruskal最大生成树&&倍增lca)
- UPC-5909 - 货物运输 - 倍增LCA
- 洛谷P1967货车运输(最大生成树 && LCA倍增)
- 【题】【二分答案&倍增(lca)】NKOJ 3560 运输计划
- poj1330 Nearest Common Ancestors(lca,tarjan&倍增)
- 倍增LCA NOIP2013 货车运输
- 洛谷1967 火车运输 kruskal求最大生成树 倍增LCA维护最小值
- NOIP 2015 Day2 T3 运输计划(二分+dfs序+树上差分+倍增LCA)
- bzoj 1787 && bzoj 1832: [Ahoi2008]Meet 紧急集合(倍增LCA)
- CodeVS3287[NOIP2013] 货车运输【Kruskal+倍增求LCA】
- 洛谷1967 火车运输 kruskal求最大生成树 倍增LCA维护最小值
- 洛谷1967 火车运输 kruskal求最大生成树 倍增LCA维护最小值
- BZOJ 1787 & 1832 [Ahoi2008]Meet 紧急集合 - 倍增LCA
- 洛谷1967 火车运输 kruskal求最大生成树 倍增LCA维护最小值
- NOIP2013 货车运输 [LCA] [RMQ] [最小生成树] [ST倍增]
- NOIP2013货车运输[lca&&kruskal]
- 洛谷1967 火车运输 kruskal求最大生成树 倍增LCA维护最小值
- [置顶] 对LCA、树上倍增、树链剖分(重链剖分&长链剖分)和LCT(Link-Cut Tree)的学习(填坑ing)
- NOIP 2013 CODE[VS] 3287 货车运输 倍增LCA || 暴力LCA + 最大生成树
- NOIP2013 货车运输 (最大生成树+树上倍增LCA)