http://www.lydsy.com/JudgeOnline/problem.php?id=3732

/*
Kruskal 最小生成树
树链剖分 最大值查询
注意:可能会有几块不联通的图
*/ #include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <ctime> using namespace std;
const int N = ; #define gc getchar()
#define lson jd << 1
#define rson jd << 1 | 1 int n, m, k, now = , tim, ans;
int bef[N], data[N], fat[N], head[N], tree[N], topp[N], fa[N], son[N], siz[N], deep[N];
struct Node_1{int u, v, w;} E[N << ];
struct Node_2{int u, v, w, nxt;} G[N << ];
struct Node_3{int l, r, Max;} T[N << ]; bool cmp(Node_1 a, Node_1 b) {return a.w < b.w;} struct Bzoj_3732{ inline int read(){
int x = ; char c = gc;
while(c < '' || c > '') c = gc;
while(c >= '' && c <= '') x = x * + c - '', c = gc;
return x;
} inline int getf(int x) {return fat[x] == x ? x : fat[x] = getf(fat[x]);}
inline void add(int u, int v, int w) {G[now].v = v; G[now].w = w; G[now].nxt = head[u]; head[u] = now ++;} inline void Kruskal(){
int js();
for(int i = ; i <= m; i ++){
int u = E[i].u, v = E[i].v;
int fu = getf(u), fv = getf(v);
if(fu != fv) {
js ++; fat[fu] = fv;
add(u, v, E[i].w);
add(v, u, E[i].w);
}
if(js == n - ) return ;
}
} void dfs_find_son(int u, int f_, int dep){
fa[u] = f_;
deep[u] = dep;
siz[u] = ;
for(int i = head[u]; ~ i; i = G[i].nxt){
int v = G[i].v;
if(v != f_){
data[v] = G[i].w;
dfs_find_son(v, u, dep + );
siz[u] += siz[v];
if(siz[v] > siz[son[u]]) son[u] = v;
}
}
} void dfs_to_un(int u, int tp){
topp[u] = tp;
tree[u] = ++ tim;
bef[tim] = u;
if(!son[u]) return ;
dfs_to_un(son[u], tp);
for(int i = head[u]; ~ i; i = G[i].nxt){
int v = G[i].v;
if(v != fa[u] && v != son[u]) dfs_to_un(v, v);
}
} void build_tree(int l, int r, int jd){
T[jd].l = l; T[jd].r = r;
if(l == r) {T[jd].Max = data[bef[l]]; return ;}
int mid = (l + r) >> ;
build_tree(l, mid, lson);
build_tree(mid + , r, rson);
T[jd].Max = max(T[lson].Max, T[rson].Max);
} void Sec_A(int l, int r, int jd, int x, int y){
if(x <= l && r <= y) {ans = max(ans, T[jd].Max); return ;}
int mid = (l + r) >> ;
if(x <= mid) Sec_A(l, mid, lson, x, y);
if(y > mid) Sec_A(mid + , r, rson, x, y);
} inline int Sec_A_imp(int x, int y){
int tp1 = topp[x], tp2 = topp[y], ret = ;
while(tp1 != tp2){
if(deep[tp1] < deep[tp2]) swap(x, y), swap(tp1, tp2);
ans = ;
Sec_A(, n, , tree[tp1], tree[x]);
ret = max(ans, ret);
x = fa[tp1];
tp1 = topp[x];
}
if(x == y) return ret;
if(deep[x] < deep[y]) swap(x, y);
ans = ;
Sec_A(, n, , tree[y] + , tree[x]);
ret = max(ret, ans);
return ret;
}
}AC; int main()
{
n = AC.read(), m = AC.read(); k = AC.read();
for(int i = ; i <= n; i ++) fat[i] = i, head[i] = -;
for(int i = ; i <= m; i ++)
E[i].u = AC.read(), E[i].v = AC.read(), E[i].w = AC.read();
sort(E + , E + m + , cmp);
AC.Kruskal();
for(int i = ; i <= n; i ++) if(!deep[i]) AC.dfs_find_son(i, , );
for(int i = ; i <= n; i ++) if(!topp[i]) AC.dfs_to_un(i, i);
AC.build_tree(, n, );
while(k --){
int x = AC.read(), y = AC.read();
int Answer = AC.Sec_A_imp(x, y);
printf("%d\n", Answer);
} return ;
}

与noip2013货车运输相似(一模一样)

货车运输:最大生成树 + 最小值查询

此题       :最小生成树 + 最大值查询

货车运输改几行代码就A了

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <string> using namespace std;
const int N = ; #define oo 99999999 struct Node{
int u, v, w;
}S[N << ];
struct Edge{
int u, v, w, nxt;
}E[N << ]; int now = , n, m, js;
int head[N], p[N], f[N][], g[N][], deep[N]; inline int read(){
int x = ; char c = getchar();
while(c < '' || c > '') c = getchar();
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x;
} inline bool cmp(Node a, Node b){
return a.w < b.w;
} int getf(int x){
return p[x] == x ? x : p[x] = getf(p[x]);
} void add(int u, int v, int w){
E[now].v = v;
E[now].w = w;
E[now].nxt = head[u];
head[u] = now ++;
} inline void Kruskal(){
for(int i = , doen = ; i <= (m << ) && doen < n; i ++){
int u = S[i].u, v = S[i].v;
int pu = getf(u), pv = getf(v);
if(pu != pv){
p[pu] = pv;
add(u, v, S[i].w);
add(v, u, S[i].w);
doen ++;
}
}
} void make_deep(int u, int depth){
deep[u] = depth;
for(int i = head[u]; ~ i; i = E[i].nxt){
int v = E[i].v;
if(!deep[v]){
f[v][] = u;
g[v][] = E[i].w;
make_deep(v, depth + );
}
}
} inline void make_jump(){
for(int j = ; ( << j) <= n; j ++)
for(int i = ; i <= n; i ++)
if(f[i][j - ]) f[i][j] = f[f[i][j - ]][j - ], g[i][j] = max(g[i][j - ], g[f[i][j - ]][j - ]);
} inline int lca(int x, int y){
int ret = -;
if(x == y) return ;
if(deep[x] < deep[y]) swap(x, y);
int k = log2(deep[x]);
for(int i = k; i >= ; i --){
if(deep[f[x][i]] >= deep[y]){
ret = max(ret, g[x][i]);
x = f[x][i];
}
}
if(x == y) return ret;
for(int i = k; i >= ; i --){
if(f[x][i] != f[y][i]){
ret = max(ret, max(g[x][i], g[y][i]));
x = f[x][i];
y = f[y][i];
}
}
ret = max(ret, max(g[x][], g[y][]));
return ret;
} int main()
{
n = read();
m = read();
int T = read();
for(int i = ; i <= n; i ++) head[i] = -, p[i] = i;
for(int i = ; i <= m; i ++) S[i].u = read(), S[i].v = read(), S[i].w = read();
sort(S + , S + m + , cmp);
Kruskal();
for(int i = ; i <= n; i ++) if(!deep[i]) make_deep(i, );//可能会有多块
make_jump();
while(T --){
int x = read(), y = read();
int answer = lca(x, y);
printf("%d\n", answer);
}
return ;
}

最新文章

  1. canvas学习笔记
  2. Win7 + ubuntu14.04 双系统安装教程
  3. php适配器设计模式
  4. 设计模式--外观(Facade)模式
  5. Android百度地图开发01之初体验
  6. [JAVA][RCP]Clean project之后报错:java.lang.RuntimeException: No application id has been found.
  7. oracle存储过程分页
  8. ASP.NET页面生命周期总结(1)
  9. UNIX环境下的共享内存
  10. C# Windows服务的创建、安装、调试
  11. 输出,变量的使用,子查询,逻辑语句,循环,case..when..then..end多分支语句,Exists(判断存在)
  12. C#图解教程-方法参数笔记(上)
  13. 编写JsonResult封装JSON返回值(模板参阅)
  14. JavaScript简单入门(补充篇)
  15. JavaScript正则表达式验证大全(收集)
  16. 深入理解vue
  17. SpringCloud Feign context-path踩到的坑
  18. cookies 不同端口 是可以共享的
  19. NHibernate 知识点整理
  20. 使用spring initialization创建SpringBoot项目

热门文章

  1. Win32小游戏--贪吃蛇
  2. beego入门笔记
  3. IIS不能下载config配置文件的解决方法
  4. 记一次构建SaaS平台项目失败后的反思(收集的客户需求太少,且没有区分重点,闭门造车。技术演变要渐进)
  5. Codeforces Round #588 (Div. 1) 简要题解
  6. java 读取文件流
  7. Spring Bean的作用域以及lookup-method标签的使用
  8. Windows下的Android Studio环境搭建、安装使用
  9. WebHost.CreateDefaultBuilder
  10. interface Part3(实现:显示和隐式)