2017多校第4场 HDU 6074 Phone Call 并查集,LCA
来源:互联网 发布:经典按键java手机游戏 编辑:程序博客网 时间:2024/06/05 00:30
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6074
题意:给你一棵树,然后给你M个条件,每次给出a,b,c,d,cost,表示从a-->b,c-->d的路径中的点,可以互相到达,花费是cost,到达具有传递性 ,现在问你从1节点最多可以到达哪些节点,最小花费是多少。
解法:看着官方题解学的。
#include <bits/stdc++.h>using namespace std;const int maxn=1e5+10;typedef long long LL;int T,n,m,parent[maxn],up[maxn],cnt[maxn];struct FastIO{ static const int S = 1310720; int wpos; char wbuf[S]; FastIO() : wpos(0) {} inline int xchar() { static char buf[S]; static int len = 0, pos = 0; if (pos == len) pos = 0, len = fread(buf, 1, S, stdin); if (pos == len) return -1; return buf[pos ++]; } inline LL Lint() { int c = xchar(); LL x = 0; while (c <= 32) c = xchar(); for (; '0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0'; return x; } inline int xint() { int s = 1, c = xchar(), x = 0; while (c <= 32) c = xchar(); if (c == '-') s = -1, c = xchar(); for (; '0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0'; return x * s; } inline void xstring(char *s) { int c = xchar(); while (c <= 32) c = xchar(); for (; c > 32; c = xchar()) * s++ = c; *s = 0; } inline void wchar(int x) { if (wpos == S) fwrite(wbuf, 1, S, stdout), wpos = 0; wbuf[wpos ++] = x; } inline void wint(LL x) { if (x < 0) wchar('-'), x = -x; char s[24]; int n = 0; while (x || !n) s[n ++] = '0' + x % 10, x /= 10; while (n--) wchar(s[n]); } inline void wstring(const char *s) { while (*s) wchar(*s++); } ~FastIO() { if (wpos) fwrite(wbuf, 1, wpos, stdout), wpos = 0; }} io;//parent[i]表示父亲节点是谁//up[i]表示i点往上深度最大的一个可能不是和i在同一个连通块的祖先//cnt[i]表示i所在连通块的点数LL w[maxn]; //i所在连通块离的距离和int dep[maxn],fa[maxn][20];//dep[i]表示i点的深度,fa[i][j]代表i跳2^j的点vector <int> G[maxn];struct node{ int a,b,c,d; LL cost; bool operator < (const node &rhs) const{ return cost < rhs.cost; }}q[maxn];//存下询问,按v值排序void dfs1(int x, int d, int pre){ dep[x] = d; fa[x][0] = pre; for(int i=1; i<20; i++){ fa[x][i] = fa[fa[x][i-1]][i-1]; } for(int i=0; i<G[x].size(); i++){ int v=G[x][i]; if(v == pre) continue; dfs1(v, d+1, x); }}int findfa(int x){ if(x==parent[x]) return x; else return parent[x] = findfa(parent[x]);}int findup(int x){ if(x == up[x]) return x; else return up[x] = findup(up[x]);}int LCA(int u, int v){ if(dep[u]<dep[v]) swap(u,v); for(int i=19; i>=0; i--){ if(dep[fa[u][i]]>=dep[v]){ u=fa[u][i]; } } if(u==v) return u; for(int i=19; i>=0; i--){ if(fa[u][i]!=fa[v][i]){ u=fa[u][i]; v=fa[v][i]; } } return fa[u][0];}void Union(int u, int v, LL cost){ u = findfa(u), v = findfa(v); if(u == v) return; parent[u] = v; cnt[v] += cnt[u]; w[v] += w[u] + cost;}void Merge(int u, int v, LL cost){ while(1){ u=findup(u); if(dep[u]<=dep[v]) return; Union(u, fa[u][0], cost); up[u] = fa[u][0]; }}void solve(node s){ int _lca = LCA(s.a, s.b); Merge(s.a, _lca, s.cost); Merge(s.b, _lca, s.cost); _lca = LCA(s.c, s.d); Merge(s.c, _lca, s.cost); Merge(s.d, _lca, s.cost); Union(s.a, s.c, s.cost);}int main(){ //freopen("1.in","r",stdin); //freopen("1.out","w",stdout); T = io.xint(); while(T--) { n = io.xint(), m = io.xint(); for(int i=0; i<=n; i++) parent[i]=up[i]=i,cnt[i]=1,w[i]=0,G[i].clear(); for(int i=1; i<n; i++){ int u, v; u = io.xint(); v = io.xint(); G[u].push_back(v); G[v].push_back(u); } for(int i=1; i<=m; i++){ //scanf("%d %d %d %d %lld", &q[i].a, &q[i].b, &q[i].c, &q[i].d, &q[i].cost); q[i].a = io.xint(); q[i].b = io.xint(); q[i].c = io.xint(); q[i].d = io.xint(); q[i].cost = io.Lint(); } sort(q+1, q+m+1); dfs1(1, 1, 0); for(int i=1; i<=m; i++) { solve(q[i]); } printf("%d %lld\n", cnt[findfa(1)], w[findfa(1)]); } return 0;}
阅读全文
0 0
- 2017多校第4场 HDU 6074 Phone Call 并查集,LCA
- HDU 6074 Phone Call (LCA+并查集, 2017 Multi-Univ Training Contest 4)
- hdu-6074 Phone Call (LCA+并查集)
- HDU6074 Phone Call(并查集,lca)
- HDU6074 Phone Call(LCA+并查集)
- hdu 2586(LCA+并查集)
- hdu 2874 Connections between cities LCA || dfs+并查集
- HDU 2874 LCA转RMQ+并查集
- |hdu 2874|LCA|并查集|Connections between cities
- poj3728并查集+LCA
- [jzoj]3875. 【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)(图论题,构树+缩点+LCA+并查集)
- LCA算法--并查集应用
- poj 3728(LCA+并查集应用)
- HDU2874并查集+(LCA-RMQ)
- POJ_3694 Network Tarjin + LCA + 并查集
- LCA Tarjin 并查集 离线
- poj3728 The merchant LCA+并查集
- POJ 3694 Network lca + 并查集
- 【修真院“正直”系列之三】【修真神界】【修行卷】【第一章】修真院入场券
- 安全防护工具之:Anchore
- 组合游戏
- 浅谈iptables
- php实现过滤中英文标点符号[gbk编码环境]
- 2017多校第4场 HDU 6074 Phone Call 并查集,LCA
- Nodejs核心模块
- linux服务器 ssh密钥登陆
- 磁盘管理
- Android 自定义圆形旋转进度条,仿微博头像加载效果
- 在Eclipse中添加C/C++插件
- HTML的组成
- [LeetCode] 541. Reverse String II
- 带你入门mysql常用命令