【题解】洛谷P1967 [NOIP2013TG] 货车运输(LCA+kruscal重构树)
洛谷P1967:https://www.luogu.org/problemnew/show/P1967
思路
感觉2013年D1T3并不是非常难
但是蒟蒻还是WA了一次
从题目描述中看出每个点之间有许多条路径
而我们需要的是找出整条路径中最大的最小可通过量
一开始看到题目会想到是不是最大流问题 但是仔细一想其实并不用那么麻烦
我们只需要用kruscal找出最大生成树即可(因为多条路径中只要挑出最大的即可)
然后在重构树上考虑怎么取到两点之间的最小值
我们发现图是一个或者是多个树(没有考虑WA了一次)
所以我们可以用LCA代替朴素算法查找最小值 用一个m1[x][k]数组维护x到x的2k辈祖先路径中的最小值
这样题目就可以轻松A过
代码
#include<iostream>
#include<algorithm>
using namespace std;
#define maxn 10010
#define INF 100010
int n,m,q,k,cnt;
int fa[maxn],f[maxn][],m1[maxn][],h[maxn],dep[maxn];
//fa为kruscal的父亲数组 f为LCA的父亲数组
bool vis[maxn];
struct Node
{
int l;
int r;
int w;
}node[maxn*];//原图的边
struct Edge
{
int nex;
int to;
int w;
}e[maxn*];//重构树的边
void add(int u,int v,int w)
{
e[++cnt].to=v;
e[cnt].w=w;
e[cnt].nex=h[u];
h[u]=cnt;
}
bool cmp(Node a,Node b)//从大到小
{
return a.w>b.w;
}
int find(int x)
{
if(fa[x]!=x)
fa[x]=find(fa[x]);
return fa[x];
}
void pre()
{
for(int i=;i<=;i++)
{
for(int j=;j<=n;j++)
{
f[j][i]=f[f[j][i-]][i-];
m1[j][i]=min(m1[j][i-],m1[f[j][i-]][i-]);//从儿子来取
}
}
}
int lca(int x,int y)
{
if(find(x)!=find(y)) return -;//如果不在同一棵树中就不能到达
int ans=INF;//初始化
if(dep[x]<dep[y]) swap(x,y);
for(int k=;k>=;k--)
{
if(dep[f[x][k]]>=dep[y])
{
ans=min(ans,m1[x][k]);//取最小值
x=f[x][k];
}
if(x==y) return ans;
}
for(int k=;k>=;k--)
{
if(f[x][k]!=f[y][k])
{
ans=min(ans,min(m1[x][k],m1[y][k]));//取最小值
x=f[x][k];
y=f[y][k];
}
}
ans=min(ans,min(m1[x][],m1[y][]));//取父亲的最小值
return ans;
}
void dfs(int u)
{
vis[u]=;//判断已经在树中
for(int i=h[u];i;i=e[i].nex)
{
int v=e[i].to;
if(vis[v]) continue;//如果在树中就跳过
dep[v]=dep[u]+;//记录深度
f[v][]=u;//记录父亲
m1[v][]=e[i].w;//初始化最小值为边权值
dfs(v);
}
return;
}
int main()
{
cin>>n>>m;
for(int i=;i<=n;i++) fa[i]=i;
for(int i=;i<=m;i++) cin>>node[i].l>>node[i].r>>node[i].w;
sort(node+,node++m,cmp);
for(int i=;i<=m;i++)//kruscal
{
if(find(node[i].l)!=find(node[i].r))
{
fa[find(node[i].l)]=find(node[i].r);
add(node[i].l,node[i].r,node[i].w);//重构图
add(node[i].r,node[i].l,node[i].w);
k++;
}
if(k==n-) break;
}
for(int i=;i<=n;i++)//预处理LCA
if(!vis[i])//判断是不是同一棵树
{
dep[i]=;//树根的深度为1
dfs(i);
f[i][]=i;//树根的父亲为自己
m1[i][]=INF;//树根到父亲的最小值为一个极大值
}
pre();//预处理m1数组和f数组
cin>>q;
for(int i=;i<=q;i++)
{
int x,y;
cin>>x>>y;
cout<<lca(x,y)<<endl;
}
}
【题解】洛谷P1967 [NOIP2013TG] 货车运输(LCA+kruscal重构树)的更多相关文章
- 【题解】【洛谷 P1967】 货车运输
目录 洛谷 P1967 货车运输 原题 题解 思路 代码 洛谷 P1967 货车运输 原题 题面请查看洛谷 P1967 货车运输. 题解 思路 根据题面,假设我们有一个普通的图: 作图工具:Graph ...
- 洛谷 P1967 货车运输(克鲁斯卡尔重构树)
题目描述 AAA国有nn n座城市,编号从 11 1到n nn,城市之间有 mmm 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 qqq 辆货车在运输货物, 司机们想知道每辆车在不超过车 ...
- NOIP 2013 提高组 洛谷P1967 货车运输 (Kruskal重构树)
题目: A 国有 nn 座城市,编号从 11 到 nn,城市之间有 mm 条双向道路.每一条道路对车辆都有重量限制,简称限重. 现在有 qq 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情 ...
- 洛谷p1967货车运输(kruskal重构树)
题面 题解中有很多说最优解是kruskal重构树 所以 抽了个早自习看了看这方面的内容 我看的博客 感觉真的挺好使的 首先对于kruskal算法来说 是基于贪心的思想把边权排序用并查集维护是否是在同一 ...
- 2018.07.22 洛谷P1967 货车运输(kruskal重构树)
传送门 这道题以前只会树剖和最小生成树+倍增. 而现在学习了一个叫做kruskal" role="presentation" style="position: ...
- 【洛谷1967】货车运输(最大生成树+倍增LCA)
点此看题面 大致题意: 有\(n\)个城市和\(m\)条道路,每条道路有一个限重.多组询问,每次询问从\(x\)到\(y\)的最大载重为多少. 一个贪心的想法 首先,让我们来贪心一波. 由于要求最大载 ...
- 洛谷P4768 [NOI2018]归程(克鲁斯卡尔重构树+最短路)
传送门 前置技能,克鲁斯卡尔重构树 我们按道路的高度建一个最大生成树,然后建好克鲁斯卡尔重构树 那么我们需要知道一颗子树内到1点距离最近是多少(除此之外到子树内任何一个点都不需要代价) 可以一开始直接 ...
- 【杂题总汇】NOIP2013(洛谷P1967) 货车运输
[洛谷P1967] 货车运输 重做NOIP提高组ing... +传送门-洛谷P1967+ ◇ 题目(copy from 洛谷) 题目描述 A国有n座城市,编号从1到n,城市之间有m条双向道路.每一条道 ...
- 洛谷P3379lca,HDU2586,洛谷P1967货车运输,倍增lca,树上倍增
倍增lca板子洛谷P3379 #include<cstdio> struct E { int to,next; }e[]; ],anc[][],log2n,deep[],n,m,s,ne; ...
随机推荐
- 1.JDBC基础
JDBC全称Java Database Connectivity,即Java数据库连接.(以下以MySQL为例,使用MySQL语句) Sun公司提供了标准JDBC API接口,没有实现具体类.各个数据 ...
- Effective C++ .07 virtual析构函数的提供
主要讲了, 1. virtual析构函数的作用与调用顺序 2. 使用时机,并不是使用了继承就要把基类的析构函数变为虚函数(virtual),只有当用于多态目的时才进行一个virtual析构函数的定义. ...
- svg基础知识体系建立
一.简介:SVG 是使用 XML 来描述二维图形和绘图程序的语言. SVG 指可伸缩矢量图形 (Scalable Vector Graphics) SVG 用来定义用于网络的基于矢量的图形 SVG 使 ...
- Python OOP面向对象
一.什么是面向对象的程序设计 1.面向过程 程序设计:核心是过程二字,过程指的是解决问题的步骤,即先干什么再干什么......面向过程的设计就好比精心设计好一条流水线,是一种机械式的思维方式. 优点是 ...
- 记录开发Nodejs c++ addon的一些经验(二、数据类型的转换(尤其是Buffer))
常见的数据类型的转换基本比较容易,结合nan应该不是一件难事 参考链接: http://blog.jobbole.com/109598/ http://deadhorse.me/nodejs/2012 ...
- linux下nginx的安装及配置
一.安装nginx前,我们首先要确保系统安装了g++.gcc.openssl-devel.pcre-devel和zlib-devel软件,可通过如图所示命令进行检测,如果以安装我们可以通过图二所示卸载 ...
- 学习C++从入门到精通的的十本最经典书籍
原文:http://blog.csdn.net/a_302/article/details/17558369 最近想学C++,找了一下网上推荐的书籍,转载过来给大家分享 转载自http://c.chi ...
- 佛系结对编程---四则运算(Core 第四组)
----by core 第四组 ( 邹卫其 范力 ) 一. 项目介绍 1. 能自动生成小学四则运算题目并给出答案,生成题目时可以选择下列参数: 1)生成题目数量 2)每道题目中运算数数量 ...
- Java基础之this关键字的作用
this关键字主要存在三种应用 1.this调用本类中的属性,也就是说调用类中的成员变量: 2.this调用本类中的其他方法: 3.this调用本类中的其他构造方法,调用时要放在构造方法的首行,否则会 ...
- 使用cocostudio 需要在Android.mk文件的配置
直接贴上Android.mk文件吧. 对了,是cocos2d3.0的,不知道2.x是否一样. LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LO ...