【kruscal】【最小生成树】【块状树】bzoj3732 Network
跟去年NOIP某题基本一样。
最小生成树之后,就变成了询问连接两点的路径上的权值最大的边。
倍增LCA、链剖什么的随便搞。
块状树其实也是很简单的,只不过每个点的点权要记录成“连接其与其父节点的边的权值”,然后暴力LCA时不要用LCA的值更新答案了。
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 15001
int Res,Num;char C,CH[];
inline int Ge()
{
Res=;C='*';
while(C<''||C>'')C=getchar();
while(C>=''&&C<=''){Res=Res*+(C-'');C=getchar();}
return Res;
}
inline void P(int x)
{
Num=;if(!x){putchar('');puts("");return;}
while(x>)CH[++Num]=x%,x/=;
while(Num)putchar(CH[Num--]+);
putchar('\n');
}
struct Edge{int u,v,w;void Read(){u=Ge();v=Ge();w=Ge();}};
bool cmp(const Edge &a,const Edge &b){return a.w<b.w;}
Edge edges[maxn<<];
struct Graph
{
int v[maxn<<],first[maxn<<],next[maxn<<],w[maxn<<],en;
void AddEdge(const int &a,const int &b)
{v[++en]=b;next[en]=first[a];first[a]=en;}
void AddEdge(const int &a,const int &b,const int &c)
{v[++en]=b;w[en]=c;next[en]=first[a];first[a]=en;}
};
Graph G[];
int fa[maxn],dep[maxn],top[maxn],siz[maxn],sz,maxv[maxn],W[maxn];
int n,m,q,x,y;
void makeblock(int cur)
{
for(int i=G[].first[cur];i;i=G[].next[i])
if(G[].v[i]!=fa[cur])
{
dep[G[].v[i]]=dep[cur]+;
W[G[].v[i]]=G[].w[i];
fa[G[].v[i]]=cur;
if(siz[top[cur]]<sz)
{
siz[top[cur]]++;
top[G[].v[i]]=top[cur];
G[].AddEdge(cur,G[].v[i]);
}
makeblock(G[].v[i]);
}
}
int rank[maxn],father[maxn];
void init(){for(int i=;i<=n;i++) father[i]=i;}
int findroot(int x)
{
if(father[x]==x) return x;
int rt=findroot(father[x]);
father[x]=rt;
return rt;
}
void Union(int U,int V)
{
if(rank[U]<rank[V]) father[U]=V;
else
{
father[V]=U;
if(rank[U]==rank[V]) rank[U]++;
}
}
void dfs(int cur,int Maxnow)
{
maxv[cur]=Maxnow;
for(int i=G[].first[cur];i;i=G[].next[i])
dfs(G[].v[i],max(Maxnow,W[G[].v[i]]));
}
int Query_max(int u,int v)
{
int res=-;
while(u!=v)
{
if(top[u]==top[v])
{
if(dep[u]<dep[v]) swap(u,v);
res=max(res,W[u]);
u=fa[u];
}
else
{
if(dep[top[u]]<dep[top[v]]) swap(u,v);
res=max(res,maxv[u]);
u=fa[top[u]];
}
}
return res;
}
int main()
{
n=Ge();m=Ge();q=Ge();
for(int i=;i<=m;i++) edges[i].Read();
sort(edges+,edges+m+,cmp);
init();
int cnt=;
for(int i=;i<=m;i++)
{
int f1=findroot(edges[i].u),f2=findroot(edges[i].v);
if(f1!=f2)
{
Union(f1,f2);
G[].AddEdge(edges[i].u,edges[i].v,edges[i].w);
G[].AddEdge(edges[i].v,edges[i].u,edges[i].w);
cnt++;
if(cnt==n-) break;
}
}
sz=sqrt(n);
for(int i=;i<=n;i++)
{
top[i]=i;
siz[i]=;
}
makeblock();
for(int i=;i<=n;i++) if(top[i]==i) dfs(i,W[i]);
for(int i=;i<=q;i++) {x=Ge();y=Ge();P(Query_max(x,y));}
return ;
}
【kruscal】【最小生成树】【块状树】bzoj3732 Network的更多相关文章
- CF891C Envy 最小生成树/虚树
正解:最小生成树/虚树 解题报告: 传送门! sd如我就只想到了最暴力的想法,一点儿优化都麻油想到,,,真的菜到爆炸了QAQ 然后就分别港下两个正解QAQ 法一,最小生成树 这个主要是要想到关于最小生 ...
- bzoj 3720: Gty的妹子树 块状树
3720: Gty的妹子树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 412 Solved: 153[Submit][Status] Descr ...
- 【块状树】bzoj3731 Gty的超级妹子树
带 加点 删边的块状树. 加点在 bzoj3720 说过. 删边其实就是块顶打标记,记录其属于哪棵树,防止在dfs搜集答案时跑到别的树上. 然后暴力把所在块拆开. 好像用邻接表存图,直接在vector ...
- 【块状树】bzoj3720 Gty的妹子树
块状树.教程见:http://z55250825.blog.163.com/blog/static/1502308092014163413858/将树按一定大小分块,分成许多子树,在每个子树的根节点记 ...
- 【块状树】【树链剖分】bzoj1036 [ZJOI2008]树的统计Count
很早之前用树链剖分写过,但是代码太长太难写,省选现场就写错了. #include<cstdio> #include<algorithm> #include<cstring ...
- 【块状树】【博弈论】bzoj3729 Gty的游戏
块状树,每个块的根记录一下当前块内距块根为奇数距离的异或和和偶数距离的异或和,询问的时候讨论一下即可. 总的节点数可能超过50000. #include<cstdio> #include& ...
- 【块状树】【树链剖分】【线段树】bzoj3531 [Sdoi2014]旅行
离线后以宗教为第一关键字,操作时间为第二关键字排序. <法一>块状树,线下ac,线上tle…… #include<cstdio> #include<cmath> # ...
- 【最近公共祖先】【块状树】CODEVS 1036 商务旅行
在线块状树LCA模板. #include<cstdio> #include<vector> #include<algorithm> #include<cmat ...
- bzoj3732: Network(最小生成树+LCA)
3732: Network 题目:传送门 题解: 第一眼就看到最大边最小,直接一波最小生成树. 一开始还担心会错,问了一波肉大佬,任意两点在最小生成树上的路径最大边一定是最小的. 那么事情就变得简单起 ...
随机推荐
- ICE学习笔记一----运行官方的java版demo程序
建议新手和我一样,从官网下载英文文档,开个有道词典,慢慢啃. 官方文档下载: http://download.csdn.net/detail/xiong_mao_1/6300631 程序代码就不说了, ...
- 【EOJ3652】乘法还原(二分图)
题意: 思路:Orz Claris 先找出所有平方项,将与有平方项的数有关的数对暂时忽略,剩下的直接连边就是一张二分图,暴力DFS染色 将有平方项的数两边都加一个,再判字典序即可 我不会判字典序……耽 ...
- 网络流专题练习Day1
04/16 一共做了8道题 首先网络流目前自己掌握的只有最大流Dinic算法和普通的费用流算法 有空还要去学习一下SAP和ZKW费用流(flag早早立在前面以后看到都有动力... 但网络流的算法个人认 ...
- [BZOJ2453]维护队列|分块
Description 你小时候玩过弹珠吗? 小朋友A有一些弹珠,A喜欢把它们排成队列,从左到右编号为1到N.为了整个队列鲜艳美观,小朋友想知道某一段连续弹珠中,不同颜色的弹珠有多少.当然,A有时候会 ...
- [BZOJ1005]Prufer数列+排列组合
一棵树的Prufer数列 每次在剩下的树中找到标号最小的叶子节点(对于无根树而言即是度数为1的节点),删去. 同时将其父节点(即与其相连的唯一点)加入Prufer数列当中. 一个Prufer数列所对应 ...
- dj定时任务
参考:http://www.mknight.cn/post/13/ https://blog.csdn.net/sicofield/article/details/50937338 一.INSTALL ...
- python 列表表达式、生成器表达式和协程函数
列表表达式.生成器表达式和协程函数 一.列表表达式: 常规方式示例: egg_list=[] for i in range(100): egg_list.append("egg%s" ...
- linux服务与进程
linux服务与进程 http://www.cnblogs.com/jamesbd/p/3567654.html linux服务与进程 1.应用程序 2.服务脚本 3.配置文件 4.查看进程 5.查看 ...
- Charles Android 抓包失败SSLHandshake: Received fatal alert: certificate_unknown
前提: Android使用Charles抓取Https请求的报文时,Android和Charles都正确安装了证书之后出现抓包失败,报错SSLHandshake: Received fatal ale ...
- SQLAlchemy中filter()和filter_by()有什么区别
from:https://segmentfault.com/q/1010000000140472 filter: apply the given filtering criterion to a co ...