[HackerRank 101 Hack 51] Train Trip
来源:互联网 发布:心动网络工资 编辑:程序博客网 时间:2024/05/15 05:53
题意
给定一棵无根树,三个人在一些点上。对于一条边,如果一个人通过代价为A,两个人同时通过代价为B,三个人同时通过代价为C。求三个人最后到达点1的最小代价。可以重复通过某点。
题解
三个人到达点1,要么三个人各自走到1,要么三个人会和在某一点后再走到1。会和时要么三个人各自走,要么某两人先会和,再一起走到会和点与第三个人会和,再一起走到1。反正总共也就几个点,倍增求LCA,然后暴力枚举方案。
代码
/// by ztx/// blog.csdn.net/hzoi_ztx#include <bits/stdc++.h>#define Rep(i,l,r) for(i=(l);i<=(r);i++)#define rep(i,l,r) for(i=(l);i< (r);i++)#define Rev(i,r,l) for(i=(r);i>=(l);i--)#define rev(i,r,l) for(i=(r);i> (l);i--)#define Each(i,v) for(i=v.begin();i!=v.end();i++)#define r(x) read(x)typedef long long ll ;typedef double lf ;int CH , NEG ;template <typename TP>inline void read(TP& ret) { ret = NEG = 0 ; while (CH=getchar() , CH<'!') ; if (CH == '-') NEG = true , CH = getchar() ; while (ret = ret*10+CH-'0' , CH=getchar() , CH>'!') ; if (NEG) ret = -ret ;}#define kN 100010LL#define infi 0x3f3f3f3f3f3f3f3fLLtemplate<typename TP>inline bool MI(TP&a,const TP&b){return a>b?a=b,true:false;}int n, v1, v2, v3;ll A, B, C, ans;int ps[10],tot;std::vector<int> g[kN];int sz[kN];int fa[18][kN], dep[kN];inline void dfs(int u,int fa=0) { ::fa[0][u] = fa; dep[u] = dep[fa]+1; for (int k=1;k<18;k++) if (::fa[k-1][u]) ::fa[k][u]=::fa[k-1][::fa[k-1][u]]; if (u==v1) sz[u]++; if (u==v2) sz[u]++; if (u==v3) sz[u]++; bool rec=false; if (sz[u]>0 || u==1) ps[++tot]=u,rec=true; for (int i=g[u].size()-1;i>=0;i--) if (g[u][i]!=fa) { dfs(g[u][i],u); if (sz[g[u][i]]) { if (!rec && sz[u]>0) ps[++tot]=u,rec=true; sz[u] += sz[g[u][i]]; } }}inline int LCA(int u,int v) { if (u == v) return u; if (dep[u]<dep[v])u^=v^=u^=v; for(int k=17;k>=0;k--) if(dep[fa[k][u]]>=dep[v]) u=fa[k][u]; if (u == v) return u; for(int k=17;k>=0;k--) if(fa[k][u]!=fa[k][v]) u=fa[k][u],v=fa[k][v]; return fa[0][u];}inline int getlen(int u,int v) { if (u == v) return 0; if (dep[u]<dep[v])u^=v^=u^=v; int ret=0; for(int k=17;k>=0;k--) if(dep[fa[k][u]]>=dep[v]) ret+=(1<<k), u=fa[k][u]; if (u == v) return ret; for(int k=17;k>=0;k--) if(fa[k][u]!=fa[k][v]) ret+=(1<<k+1),u=fa[k][u],v=fa[k][v]; return ret+2;}inline ll getreallen(int a,int b,int c) { int lca = LCA(a,b); int llca = LCA(lca,c); ll now = A*getlen(a,b)+B*getlen(lca,c); if (dep[llca] < dep[lca]) { return now; } else { int lca1 = LCA(a,c); int lca2 = LCA(b,c); MI(now,A*getlen(a,b)+B*getlen(lca1,c)); MI(now,A*getlen(a,b)+B*getlen(lca2,c)); return now; }}inline void calc() { ans = infi; for(int i=1;i<=tot;i++) { MI(ans,A*(getlen(v1,ps[i])+getlen(v2,ps[i])+getlen(v3,ps[i]))+C*getlen(1,ps[i])); MI(ans,getreallen(v1,v2,ps[i])+A*getlen(v3,ps[i])+C*getlen(1,ps[i])); MI(ans,getreallen(v2,v3,ps[i])+A*getlen(v1,ps[i])+C*getlen(1,ps[i])); MI(ans,getreallen(v1,v3,ps[i])+A*getlen(v2,ps[i])+C*getlen(1,ps[i])); }}inline void work() { memset(fa,0,sizeof fa); int i, u, v; Rep (i,1,n) g[i].clear(), sz[i]=0; tot = 0; r(n), r(A), r(B), r(C), r(v1), r(v2), r(v3); rep(i,1,n) r(u), r(v), g[u].push_back(v),g[v].push_back(u); dfs(1); calc(); printf("%lld\n", ans);}int main() { int T; r(T); while (T --> 0) work(); END: getchar(), getchar(); return 0;}
阅读全文
0 0
- [HackerRank 101 Hack 51] Train Trip
- [HackerRank 101 Hack 51] Small Cubes
- [HackerRank 101 Hack 51] Testing the Game
- Hackerrank 101 Hack 42 Array Pairs
- [HackerRank 101 Hack 42]Array Pairs
- 【Hackerrank 101Hack 43】【JZOJ5135】K-Inversion Permutations 题解
- [Hackerrank 101 Hack 43&& MenciOJ P321] K-Inversion Permutations
- 【Hackerrank World11】Road Trip 题解
- [线段树][单调栈]HackerRank 101 Hack 50 .Boxes for Toys
- [线段树 || 主席树][Hash] HackerRank 101 Hack 49. Sorting Lists
- hackerRank
- HackerRank
- HackerRank
- HackerRank
- HackerRank
- HackerRank
- HackerRank
- Trip
- node __dirname __filename
- 总结:大功率发射1
- 图像标签
- Android中的EditText默认时不弹出软键盘的方法
- HTML5-照片移动
- [HackerRank 101 Hack 51] Train Trip
- 【CodeForces
- 带空格的字符串输入
- HDU6103Kirinriki(尺取)
- JavaScript学习 ---1
- MyEclipse 如何清除记录的工作空间
- 寻找和为定值的n个数
- 如何在Linux下安装软件,以移植安装libjpeg解码库为例(总结)
- laravel---路由分割