题目大意

给出一张图,给出q对点,求这两个点间权值最小边最大的路径,输出这个最小边权。

题解

我们先一条一条边建图。当建立的边使得图中形成环时,因为环中的每个节点只考虑是否连通和瓶颈大小,要想互相连通只要一条路就够了,而只有环上的最小边和次小边可能是这条路的瓶颈,且这条路的瓶颈肯定越大越好。故根据贪心,我们可以直接把环中的权值最小边删去。

所以我们就维护一个LCT来随时删边增边,还要用到拆边等方法来统计路径上的值吗?能AC,但太复杂了!

我们从整体考虑,第一段叙述中,每次遇到一个环,其值为S。由于去掉的是最小边,边权w,所以剩余的路径上的边权和S-w是最大的。所以这就是一个最大生成树。所以我们就用Kruskal算法求出最大生成树,再由树上倍增求解即可。注意Kruskal处理的是单向边而不是无向图,所以先Kruskal,再建图。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdarg>
using namespace std; const int MAX_NODE = 10010, MAX_EDGE = 50010 * 2, MAX_LOG = 20, INF = 0x3f3f3f3f; struct Node;
struct Edge; struct Node {
Edge *Head;
Node *Elder[MAX_LOG];
Node *Root;
int MinVal[MAX_LOG];
int Depth;
Node *Father;
}_nodes[MAX_NODE], *CurRoot;
int _vCount; struct Edge {
Node *From, *To;
Edge *Next;
int Weight;
Edge(Node *from, Node *to, int w):From(from),To(to),Weight(w),Next(NULL){}
Edge() {}
}_edges[MAX_NODE * 2], tempEdges[MAX_EDGE];
int _eCount, tempeCount; Edge *NewEdge() {
return _edges + (++_eCount);
} Edge *AddEdge(Node *from, Node *to, int w) {
Edge *e = NewEdge();
e->To = to;
e->From = from;
e->Weight = w;
e->Next = from->Head;
from->Head = e;
return e;
} void Build(int uId, int vId, int w) {
tempEdges[++tempeCount] = Edge(_nodes + uId, _nodes + vId, w);
} int Log2(int x) {
int ans = 0;
while (x >>= 1)
ans++;
return ans;
} void Dfs(Node *cur, Edge *FromFa) {
cur->Root = CurRoot;
if (FromFa == NULL) {
cur->Depth = 1;
cur->MinVal[0] = INF;
}
else {
cur->Elder[0] = FromFa->From;
cur->Depth = cur->Elder[0]->Depth + 1;
cur->MinVal[0] = FromFa->Weight;
for (int i = 1; cur->Elder[i - 1]->Elder[i - 1]; i++) {
cur->Elder[i] = cur->Elder[i - 1]->Elder[i - 1];
cur->MinVal[i] = min(cur->MinVal[i - 1], cur->Elder[i - 1]->MinVal[i - 1]);
}
}
for (Edge *e = cur->Head; e; e = e->Next)
if (e->To != cur->Elder[0])
Dfs(e->To, e);
} void DfsStart() {
for (int i = 1; i <= _vCount; i++) {
if (!_nodes[i].Depth) {
CurRoot = _nodes + i;
Dfs(CurRoot, NULL);
}
}
} int Lca(Node *deep, Node *high) {
if (deep->Root != high->Root)
return -1;
int ans = INF;
if (deep->Depth < high->Depth)
swap(deep, high);
int len = deep->Depth - high->Depth;
for (int k = 0; len; k++) {
if ((1 << k)&len) {
ans = min(ans, deep->MinVal[k]);
deep = deep->Elder[k];
len -= (1 << k);
}
}
if (deep == high)
return ans;
for (int k = Log2(deep->Depth); k >= 0; k--) {
if (deep->Elder[k] != high->Elder[k]) {
ans = min(ans, deep->MinVal[k]);
ans = min(ans, high->MinVal[k]);
deep = deep->Elder[k];
high = high->Elder[k];
}
}
ans = min(ans, deep->MinVal[0]);
ans = min(ans, high->MinVal[0]);
return ans;
} bool CmpEdge(Edge a, Edge b) {
return a.Weight > b.Weight;
} Node *FindFather(Node *cur) {
return cur == cur->Father ? cur : cur->Father = FindFather(cur->Father);
} void Join(Node *root1, Node *root2) {
root1->Father = root2;
} void Kruskal() {
sort(tempEdges + 1, tempEdges + tempeCount + 1, CmpEdge);
for (int i = 1; i <= _vCount; i++)
_nodes[i].Father = _nodes + i;
for (int i = 1; i <= tempeCount; i++) {
Edge e = tempEdges[i];
Node *root1 = FindFather(e.From), *root2 = FindFather(e.To);
if (root1 != root2) {
AddEdge(e.From, e.To, e.Weight);
AddEdge(e.To, e.From, e.Weight);
Join(root1, root2);
}
}
} int main() {
int totEdge;
scanf("%d%d", &_vCount, &totEdge);
for (int i = 1; i <= totEdge; i++) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
Build(u, v, w);
}
Kruskal();
DfsStart();
int queryCnt;
scanf("%d", &queryCnt);
while (queryCnt--) {
int u, v;
scanf("%d%d", &u, &v);
printf("%d\n", Lca(_nodes + u, _nodes + v));
}
return 0;
}

luogu1967 货车运输 最大瓶颈生成树的更多相关文章

  1. NOIP2013 货车运输(最大生成树,倍增)

    NOIP2013 货车运输(最大生成树,倍增) A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物,司机们想知道 ...

  2. NOIP2013 货车运输 (最大生成树+树上倍增LCA)

    死磕一道题,中间发现倍增还是掌握的不熟 ,而且深刻理解:SB错误毁一生,憋了近2个小时才调对,不过还好一遍AC省了更多的事,不然我一定会疯掉的... 3287 货车运输 2013年NOIP全国联赛提高 ...

  3. 「NOIP2013」「LuoguP1967」货车运输(最大生成树 倍增 LCA

    题目描述 AA国有nn座城市,编号从 11到nn,城市之间有 mm 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 qq 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最 ...

  4. $Noip2013/Luogu1967$ 货车运输 最大生成树+倍增$lca$

    $Luogu$ $Sol$ 首先当然是构建一棵最大生成树,然后对于一辆货车的起点和终点倍增跑$lca$更新答案就好.记得预处理倍增的时候不仅要处理走了$2^i$步后是那个点,还有这中间经过的路径权值的 ...

  5. [洛谷 P1967] 货车运输 (最大生成树 lca)

    题目描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多 ...

  6. [NOIP2013/Codevs3287]货车运输-最小[大]生成树-树上倍增

    Problem 树上倍增 题目大意 给出一个图,给出若干个点对u,v,求u,v的一条路径,该路径上最小的边权值最大. Solution 看到这个题第一反应是图论.. 然而,任意路径最小的边权值最大,如 ...

  7. [luogu1967][货车运输]

    题目链接 题意: 其实题目的意思就是问从x到y权值最小的路的权值最大能是多少. 思路: 首先可以先把这张图变成一棵树.因为那些更小的点肯定是不跑更优秀,而且题目没有要求路程,所以生成一棵树,只要能保证 ...

  8. 货车运输(最大生成树+倍增LCA)

    看到第一篇题解的神奇码风--我决定发一篇码风正常的题解造福人类 这题的做法也非常经典,最大生成树\(+LCA\),相当于先贪心一下,在LCA的时候记录一下当前最小的边权 顺便吐槽一下最后一个测试点: ...

  9. Luogu P1967 货车运输 倍增+最大生成树

    看见某大佬在做,决定补一发题解$qwq$ 首先跑出最大生成树(注意有可能不连通),然后我们要求的就是树上两点间路径上的最小边权. 我们用倍增的思路跑出来$w[u][j]$,表示$u$与的它$2^j$的 ...

随机推荐

  1. 35个jquery小技巧

    1. 禁止右键点击 ? 1 2 3 4 5 $(document).ready(function(){     $(document).bind("contextmenu",fun ...

  2. Android fragment的切换(解决REPLACE的低效)

    在项目中切换Fragment,一直都是用replace()方法来替换Fragment.但是这样做有一个问题,每次切换的时候Fragment都会重新实列化,重新加载一次数据,这样做会非常消耗性能用用户的 ...

  3. Retrofit 传递json 和 复杂参数类型List<T>

    1 首先你要定义一个接口 @POST Call<String> post(@Url String url, @Body String info); 2 创建一个service public ...

  4. Css打造一个简单的静态七巧板

    偶然在微博上看到用css写一个七巧板,正好也有一些源代码,于是就试着敲了敲. 主要是利用了css3的transform,实现平移,旋转,变形,直接用看到的代码敲出来之后有些问题,因为宽度上下面绿色的三 ...

  5. Linux学习自动化脚本(一)

    https://www.cnblogs.com/handsomecui/p/5869361.html https://blog.csdn.net/daigualu/article/details/76 ...

  6. 【sqli-labs】 less27 GET- Error based -All you Union&Select Belong to us -String -Single quote(GET型基于错误的去除了Union和Select的单引号字符型注入)

    看一下过滤函数 看一下/s是什么东西 那直接通过大小写就可以绕过了 http://192.168.136.128/sqli-labs-master/Less-27/?id=0'%a0uNion%a0s ...

  7. JSP_内置对象_session

    session表示客户端与服务器的一次会话. Web中的session指的是用户在浏览某个网站时,从进入网站到浏览器关闭所经过的这段时间,也就是用户浏览这个网站所花费的时间. 从上述定义中可以看到,s ...

  8. iOS安全策略之HTTPS

    1.HTTPS传输流程 2.常用加密算法 3.AFN证书校验策略及核心方法 4.SSL Pinning 5.CA证书申请流程 HTTPS经由超文本传输协议进行通信,但利用SSL/TLS来对数据包进行加 ...

  9. Express+Nodejs 下的登录拦截实现

    Express+Nodejs 下的登录拦截实现 利用商城举例,在商城中没有登录之前,可以看商品列表.详情.登录或者注册都可以,但是购买的时候是不行的,那么这个功能在Node后台中是怎么实现的呢,这个功 ...

  10. javaee IO流作业

    package Zy; import java.io.Serializable; public class Student implements Serializable{ private stati ...