【题目链接】

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)的更多相关文章

  1. BZOJ 3732: Network 最小生成树 倍增

    3732: Network 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=3732 Description 给你N个点的无向图 (1 &l ...

  2. BZOJ 3732 Network —— 最小生成树 + 倍增LCA

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3732 Description 给你N个点的无向图 (1 <= N <= 15, ...

  3. BZOJ 3732 Network Kruskal+倍增LCA

    题目大意:给定一个n个点m条边的无向连通图.k次询问两点之间全部路径中最长边的最小值 NOIP2013 货车运输.差点儿就是原题...仅仅只是最小边最大改成了最大边最小.. . 首先看到最大值最小第一 ...

  4. BZOJ 3732 Network

    2016.1.28 纪念我BZOJ第一题 Description 给你N个点的无向图 (1 <= N <= 15,000),记为:1…N. 图中有M条边 (1 <= M <= ...

  5. bzoj 3732: Network 树上两点边权最值

    http://www.lydsy.com/JudgeOnline/problem.php?id=3732 首先想到,要使得最长边最短,应该尽量走最短的边,在MST上. 然后像LCA那样倍增娶个最大值 ...

  6. BZOJ 3732 Network Link-Cut-Tree (我是认真的!!

    题目大意:给定一个n个点m条边的无向连通图.k次询问两点之间全部路径中最长边的最小值 LCT的裸题! 首先维护一个动态的最小生成树,然后每次增加边时删除两点间路径上权值最大的边.最后询问时直接求x到y ...

  7. bzoj 3732: Network【克鲁斯卡尔+树链剖分】

    先做最小生成树,这样就保证了最大值最小 然后随便用个什么东西维护一下最大值,我用的树剖log^2,倍增会更快 #include<iostream> #include<cstdio&g ...

  8. BZOJ 3732 Network 【模板】kruskal重构树

    [题解] 首先,我们可以发现,A到B的所有路径中,最长边的最小值一定在最小生成树上.我们用Kruskal最小生成树时,假设有两个点集U,V,若加入一条边w(u,v)使U,V联通,那么w就是U中每个点到 ...

  9. Kruskal重构树+LCA || BZOJ 3732: Network

    题面:https://www.lydsy.com/JudgeOnline/problem.php?id=3732 题解:Kruskal重构树板子 代码: #include<cstdio> ...

随机推荐

  1. 利用Nginx搭建http和rtmp协议的流媒体服务器

    http://www.linuxidc.com/Linux/2013-02/79118.htm

  2. HTML 中的meta标签中的http-equiv与name属性使用介绍

    meta是html语言head区的一个辅助性标签.也许你认为这些代码可有可无.其实如果你能够用好meta标签,会给你带来意想不到的效果,meta标签的作用有:搜索引擎优化(SEO),定义页面使用语言, ...

  3. Burnside引理和polay计数学习小记

    在组合数学中有这样一类问题,比如用红蓝两种颜色对2*2的格子染色,旋转后相同的算作一种.有多少种不同的染色方案?我们列举出,那么一共有16种.但是我们发现,3,4,5,6是同一种,7,8,9,10是用 ...

  4. typeof和GetType的区别

    http://stackoverflow.com/questions/4537945/what-is-the-difference-of-getting-type-by-using-gettype-a ...

  5. VS2010中如果忘记函数所在的头文件或者忘记函数的输入输出参数类型怎么办?

    先随便找一个熟悉的函数,右击-转到定义,然后写出目标函数,右击-转到定义

  6. bzoj3672

    感觉是noi2014中最有价值的一道题了 我们先考虑链上这个问题怎么做…… 如果没限制,那就是SB的斜率优化 我们可以得到这个式子(f[j]-f[k])/(s[j]-s[k])<p[i] 点横坐 ...

  7. Linux“Bash”漏洞大爆发

    9月25日,国外曝出一个“毁灭级”的Bash漏洞,黑客可利用此漏洞远程执行任意命令,完全控制目标系统! 该漏洞编号为CVE-2014-6271,主要存在于bash 1.14 - 4.3版本中,受影响的 ...

  8. JQuery Ajax 在asp.net中使用小结

    自从有了JQuery,Ajax的使用变的越来越方便了,但是使用中还是会或多或少的出现一些让人短时间内痛苦的问题.本文暂时总结一些在使用JQuery Ajax中应该注意的问题,如有不恰当或者不完善的地方 ...

  9. Android-Universal-Image-Loader

    基本以后都不用了,所以自己就不总结了 http://www.cnblogs.com/kissazi2/p/3886563.html http://www.cnblogs.com/kissazi2/p/ ...

  10. Android Broadcast Receiver

    说明 有时候我们在做android系统软件的时候,经常会需要做的事就是开机重新设置上次关机前的状态,当然,我们就会用到这个开机广播: <uses-permission android:name= ...