bzoj 3732 Network(最短路+倍增 | LCT)
【题目链接】
http://www.lydsy.com/JudgeOnline/problem.php?id=3732
【题意】
给定一个无向图,处理若干询问:uv路径上最长的边最小是多少?
【思路一】
最小生成树+倍增算法。
同NOIP2013货车运输。
【代码】
#include<set>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define trav(u,i) for(int i=front[u];i;i=e[i].nxt)
#define FOR(a,b,c) for(int a=(b);a<=(c);a++)
using namespace std; typedef long long ll;
const int N = 1e5+;
const int M = 2e5+;
const int D = ;
const int inf = 2e9; ll read() {
char c=getchar();
ll f=,x=;
while(!isdigit(c)) {
if(c=='-') f=-; c=getchar();
}
while(isdigit(c))
x=x*+c-'',c=getchar();
return x*f;
} struct Edge {
int u,v,w,nxt;
bool operator < (const Edge& rhs) const{
return w<rhs.w;
}
}e[M];
int en=,front[N];
void adde(int u,int v,int w)
{
e[++en]=(Edge){u,v,w,front[u]}; front[u]=en;
}
vector<Edge> es; int n,m,K,p[N],_max[N][D],fa[N][D],dep[N]; int ifind(int u)
{
return u==p[u]? u:p[u]=ifind(p[u]);
} void Kruskal()
{
sort(es.begin(),es.end());
FOR(i,,(int)es.size()-) {
int u=es[i].u,v=es[i].v,w=es[i].w;
int x=ifind(u),y=ifind(v);
if(x!=y) {
p[x]=y;
adde(u,v,w); adde(v,u,w);
}
}
}
void dfs(int u,int father)
{
trav(u,i) {
int v=e[i].v;
if(v!=father) {
fa[v][]=u;
_max[v][]=e[i].w;
dep[v]=dep[u]+;
FOR(j,,D-) {
fa[v][j]=fa[fa[v][j-]][j-];
_max[v][j]=max(_max[v][j-],_max[fa[v][j-]][j-]);
}
dfs(v,u);
}
}
} int query(int u,int v)
{
if(dep[u]<dep[v]) swap(u,v);
int t=dep[u]-dep[v],ans=-inf;
FOR(i,,D-)
if(t&(<<i)) {
ans=max(ans,_max[u][i]);
u=fa[u][i];
}
if(u==v) return ans;
for(int i=D-;i>=;i--)
if(fa[u][i]!=fa[v][i]) {
ans=max(ans,max(_max[u][i],_max[v][i]));
u=fa[u][i],v=fa[v][i];
}
ans=max(ans,max(_max[u][],_max[v][]));
return ans;
} int main()
{
n=read(),m=read(),K=read();
FOR(i,,n) FOR(j,,D-) _max[i][j]=-inf;
FOR(i,,n) p[i]=i;
FOR(i,,m) {
int u=read(),v=read(),w=read();
es.push_back((Edge){u,v,w,});
}
Kruskal();
dfs(,-);
FOR(i,,K) {
int u=read(),v=read();
printf("%d\n",query(u,v));
}
return ;
}
【思路二】
用LCT换个姿势AC。LCT维护最小生成树?
给每条边每个点开一个LCT结点,边的maxe初始为自己,点的maxe为0。对于新加的一条边,找到u->v目前的最大边与之比较,如果更小则切断原来的边连上新的边。u,v之间连边的时候以边界点为中间点。
【代码】
#include<cstdio>
#include<cstring>
#include<iostream>
#define FOR(a,b,c) for(int a=b;a<=c;a++)
#define trav(u,i) for(int i=front[u];i;i=e[i].nxt)
using namespace std; typedef long long ll;
typedef unsigned int ul;
const int N = 4e5+; ll read() {
char c=getchar();
ll f=,x=;
while(!isdigit(c)) {
if(c=='-') f=-; c=getchar();
}
while(isdigit(c))
x=x*+c-'',c=getchar();
return x*f;
} struct Edge { int u,v,w;
}e[N<<]; namespace LCT { struct Node {
Node *ch[],*fa;
int rev,id,maxe;
Node() ;
void reverse() {
rev^=;
swap(ch[],ch[]);
}
void up_push() {
if(fa->ch[]==this||fa->ch[]==this)
fa->up_push();
if(rev) {
ch[]->reverse();
ch[]->reverse();
rev=;
}
}
void maintain() {
int _max=-;
if(e[ch[]->maxe].w>_max)
_max=e[ch[]->maxe].w,maxe=ch[]->maxe;
if(e[ch[]->maxe].w>_max)
_max=e[ch[]->maxe].w,maxe=ch[]->maxe;
if(e[id].w>_max) maxe=id;
}
} *null=new Node,T[N],E[N<<];
Node::Node() {
id=maxe=rev=;
fa=ch[]=ch[]=null;
} void rot(Node* o,int d) {
Node *p=o->fa;
p->ch[d]=o->ch[d^];
o->ch[d^]->fa=p;
o->ch[d^]=p;
o->fa=p->fa;
if(p==p->fa->ch[])
p->fa->ch[]=o;
else if(p==p->fa->ch[])
p->fa->ch[]=o;
p->fa=o;
p->maintain();
}
void splay(Node *o) {
o->up_push();
Node *nf,*nff;
while(o->fa->ch[]==o||o->fa->ch[]==o) {
nf=o->fa,nff=nf->fa;
if(o==nf->ch[]) {
if(nf==nff->ch[]) rot(nf,);
rot(o,);
} else {
if(nf==nf->ch[]) rot(nf,);
rot(o,);
}
}
o->maintain();
}
void Access(Node* o) {
Node *son=null;
while(o!=null) {
splay(o);
o->ch[]=son;
o->maintain();
son=o; o=o->fa;
}
}
void evert(Node* o) {
Access(o);
splay(o);
o->reverse();
}
void Link(Node* u,Node* v) {
evert(u);
u->fa=v;
}
void Cut(Node* u,Node* v) {
evert(u);
Access(v); splay(v);
u->fa=v->ch[]=null;
v->maintain();
}
Node* find(Node* o) {
while(o->fa!=null) o=o->fa;
return o;
} }
using namespace LCT; const int inf = 1e9+; int n,m,K; int query(Node *u,Node *v)
{
evert(u);
Access(v),splay(v);
return v->maxe;
}
void insert(Node *u,Node *v,int x)
{
if(e[x].u==e[x].v) return ;
if(find(u)==find(v)) {
int maxe=query(u,v);
if(e[x].w>=e[maxe].w) return ;
Cut(&E[maxe],&T[e[maxe].v]);
Cut(&E[maxe],&T[e[maxe].u]);
}
Link(u,&E[x]);
Link(v,&E[x]);
} int main()
{
n=read(),m=read(),K=read();
FOR(i,,m) E[i].id=E[i].maxe=i;
FOR(i,,m) {
e[i].u=read(),e[i].v=read(),e[i].w=read();
insert(&T[e[i].u],&T[e[i].v],i);
}
FOR(i,,K) {
int u=read(),v=read();
printf("%d\n",e[query(&T[u],&T[v])].w);
}
return ;
}
bzoj 3732 Network(最短路+倍增 | LCT)的更多相关文章
- BZOJ 3732: Network 最小生成树 倍增
3732: Network 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=3732 Description 给你N个点的无向图 (1 &l ...
- BZOJ 3732 Network —— 最小生成树 + 倍增LCA
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3732 Description 给你N个点的无向图 (1 <= N <= 15, ...
- BZOJ 3732 Network Kruskal+倍增LCA
题目大意:给定一个n个点m条边的无向连通图.k次询问两点之间全部路径中最长边的最小值 NOIP2013 货车运输.差点儿就是原题...仅仅只是最小边最大改成了最大边最小.. . 首先看到最大值最小第一 ...
- BZOJ 3732 Network
2016.1.28 纪念我BZOJ第一题 Description 给你N个点的无向图 (1 <= N <= 15,000),记为:1…N. 图中有M条边 (1 <= M <= ...
- bzoj 3732: Network 树上两点边权最值
http://www.lydsy.com/JudgeOnline/problem.php?id=3732 首先想到,要使得最长边最短,应该尽量走最短的边,在MST上. 然后像LCA那样倍增娶个最大值 ...
- BZOJ 3732 Network Link-Cut-Tree (我是认真的!!
题目大意:给定一个n个点m条边的无向连通图.k次询问两点之间全部路径中最长边的最小值 LCT的裸题! 首先维护一个动态的最小生成树,然后每次增加边时删除两点间路径上权值最大的边.最后询问时直接求x到y ...
- bzoj 3732: Network【克鲁斯卡尔+树链剖分】
先做最小生成树,这样就保证了最大值最小 然后随便用个什么东西维护一下最大值,我用的树剖log^2,倍增会更快 #include<iostream> #include<cstdio&g ...
- BZOJ 3732 Network 【模板】kruskal重构树
[题解] 首先,我们可以发现,A到B的所有路径中,最长边的最小值一定在最小生成树上.我们用Kruskal最小生成树时,假设有两个点集U,V,若加入一条边w(u,v)使U,V联通,那么w就是U中每个点到 ...
- Kruskal重构树+LCA || BZOJ 3732: Network
题面:https://www.lydsy.com/JudgeOnline/problem.php?id=3732 题解:Kruskal重构树板子 代码: #include<cstdio> ...
随机推荐
- java--依赖、关联、聚合和组合之间区别的理解
在学习面向对象设计对象关系时,依赖.关联.聚合和组合这四种关系之间区别比较容易混淆.特别是后三种,仅仅是在语义上有所区别,所谓语义就是指上下文环境.特定情景等. 依赖(Dependency)关系是类与 ...
- React组件测试(模拟组件、函数和事件)
一.模拟组件 1.用到的工具 (1)browerify (2)jasmine-react-helpers (3)rewireify(依赖注入) (4)命令:browserify - t reactif ...
- Android开发之MD5加密
将字符串进行MD5加密,返回加密后的字符串 public static String encode(String password) { try { StringBuffer sb = new Str ...
- JS对象基础
JavaScript 对象 JavaScript 提供多个内建对象,比如 String.Date.Array 等等. 对象只是带有属性和方法的特殊数据类型. 访问对象的属性 属性是与对象相关的值. 访 ...
- 12 Useful “df” Commands to Check Disk Space in Linux
On the internet you will find plenty of tools for checking disk space utilization in Linux. However, ...
- Android加速度传感器实现“摇一摇”,带手机振动
由于代码有点多,所以就分开写了,注释还算详细,方便学习 Activity package com.lmw.android.test; import android.app.Activity; im ...
- UVa 10868 (物理) Bungee Jumping
题意: 有个人在蹦极,给出悬崖的高度,绳子的长度,弹簧绳的胡克系数 以及 人的质量. 判断人是否能够着地,能的话是否能安全着地.所谓安全着地就是到达地面的速度不超过10m/s. 分析: 学过一点高中物 ...
- ASP.NET MVC从客户端中检测到有潜在危险的 Request.Form 值
ASP.NET MVC4(Razor)从客户端中检测到有潜在危险的 Request.Form 值 “/”应用程序中的服务器错误. 从客户端(Content=" sdfdddd ...&quo ...
- IE6、IE7、IE8中overflow:hidden无效问题
在做图片无缝滚动效果时遇到了这个兼容问题 div宽1000px高250px超出隐藏. 但在Firefox中正常,超出部分隐藏,但是在IE6.IE7.IE8.Sogou高速下都显示了出来.做了这么多年的 ...
- Android Studio 我常用快捷键
0. Ctrl+Alt+L 格式化代码 Ctrl+Alt+O 优化导入的类 1. 重载方法 Ctrl+O 2.Ctrl+shift+Enter:自动匹配相对应的语法结构,比如if,do-while,t ...