【NOIP2013】货车运输
感觉这题挺水的……真的挺水的……
原题:
A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路。每一条道路对车辆都有重量限制,简称限重。现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物。
0 < n < 10,000,0 < m < 50,000,0 < q < 30,000,0 ≤ z ≤ 100,000。
思路非常简单,求最大生成树,然后剖,甚至连修改操作都没有
这题水啊,二分就有60,正解就是个裸的生成树+剖
如果NOIP考自己学过的比较高级的高级数据结构是一件挺好的事,受到NOIP难度的限制,考比较高级的东西的话就会裸得多,就没有呢么多魔性的东西了(然而因为选手水平提升而难度增加的概率非常大QAQ)
有几点需要注意的地方,因为这里要用点的权值当边的权值,所以在路径遇到拐点(就是deep[x]>deep[y]<deep[z])的时候要特判一下,首先如果最后到一条重链上的时候x和y一样的话就不找了,因为这个点就是拐点,查找的话结果会是拐点和它的父节点之间的边,就跟路径没关系了,如果查找的话,查找左端点要是深度比较浅的内个点的标号+1,因为深度比较浅的内个点的值是它和它父节点之间连的边的值,但是在往同一个重链上攀的时候就不用这么判断了,因为不+1的话刚好把重链顶点和它的父节点之间的边算上了,就不用再算一遍了
第一次写成树剖,这个东西终于懂了QAQ,收货还是挺多的
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int read(){int z=,mark=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')mark=-; ch=getchar();}
while(ch>=''&&ch<=''){z=(z<<)+(z<<)+ch-''; ch=getchar();}
return z*mark;
}
struct ddd{int next,y,value;}e[];int LINK[],ltop=;
inline void insert(int x,int y,int z){e[++ltop].next=LINK[x];LINK[x]=ltop;e[ltop].y=y;e[ltop].value=z;}
struct ccc{int x,y,value;}tu[];int tltop=;
inline void insert_tu(int x,int y,int z){tu[++tltop].x=x,tu[tltop].y=y,tu[tltop].value=z;}
struct dcd{int sleft,sright,mid,svalue;}tree[];
int n,m;
int size[],deep[],father[],big_child[],top[];
int dfs_xv[],fan_xv[],cnt=,b_value[];
int ji[];
int group[],gtop=;
int cha(int x){ if(ji[x]==x) return x; ji[x]=cha(ji[x]); return ji[x];}
void bing(int x,int y){ int ji_x=cha(x),ji_y=cha(y); ji[ji_x]=ji_y;}
bool compare(ccc x,ccc y){ return x.value>y.value;}//这里求的是最大生成树
void kruskal(){
for(int i=;i<=n;i++) ji[i]=i;
sort(tu+,tu+tltop+,compare);
int _cnt=;
for(int i=;i<=tltop;i++){
int _x=cha(tu[i].x),_y=cha(tu[i].y);
if(_x!=_y){
bing(_x,_y);
insert(tu[i].x,tu[i].y,tu[i].value),insert(tu[i].y,tu[i].x,tu[i].value);
if(++_cnt==n-) return ;
}
}
}
void dfs1(int x,int _deep,int _father){
group[x]=gtop;
father[x]=_father,deep[x]=_deep,size[x]=;
int max_size=,max_child=;
for(int i=LINK[x];i;i=e[i].next)if(e[i].y!=_father){
dfs1(e[i].y,_deep+,x);
b_value[e[i].y]=e[i].value;
size[x]+=size[e[i].y];
if(size[e[i].y]>max_size){ max_size=size[e[i].y]; max_child=e[i].y;}
}
big_child[x]=max_child;
}
void dfs2(int x,int _top){
top[x]=_top; dfs_xv[++cnt]=x; fan_xv[x]=cnt;
if(big_child[x]) dfs2(big_child[x],_top);
for(int i=LINK[x];i;i=e[i].next)if(e[i].y!=father[x] && e[i].y!=big_child[x])
dfs2(e[i].y,e[i].y);
}
void get_SegmentTree(int x,int _left,int _right){
tree[x].sleft=_left,tree[x].sright=_right,tree[x].mid=(_left+_right)>>;
if(_left==_right) tree[x].svalue=b_value[dfs_xv[_left]];//注意这里
else{
get_SegmentTree(x<<,_left,tree[x].mid),get_SegmentTree(x<<|,tree[x].mid+,_right);
tree[x].svalue=min(tree[x<<].svalue,tree[x<<|].svalue);
}
}
int search(int x,int _left,int _right){
if(tree[x].sleft==_left && tree[x].sright==_right) return tree[x].svalue;
else if(_left<=tree[x].mid && _right>tree[x].mid) return min(search(x<<,_left,tree[x].mid),search(x<<|,tree[x].mid+,_right));
else if(_right<=tree[x].mid) return search(x<<,_left,_right);
else return search(x<<|,_left,_right);
}
int pa(int x,int y){
int minn=;
int fa=top[x],fb=top[y];
while(fa!=fb){
if(deep[fa]<deep[fb]) swap(fa,fb),swap(x,y);
minn=min(minn,search(,fan_xv[fa],fan_xv[x]));//注意这里是x
x=father[fa]; fa=top[x];
}
if(deep[x]>deep[y]) swap(x,y);
if(x!=y) minn=min(minn,search(,fan_xv[x]+,fan_xv[y]));//注意,如果不加判断会把拐点和拐点的父节点之间的连边也算进去,而且注意+1
return minn;
}
int main(){//freopen("ddd.in","r",stdin); freopen("ddd.out","w",stdout);
memset(group,,sizeof(group));
cin>>n>>m;
int _left,_right,_value;
while(m --> ){//趋向于
_left=read(),_right=read(),_value=read();
insert_tu(_left,_right,_value);
}
kruskal();
for(int i=;i<=n;i++)if(!group[i]){ b_value[i]=; gtop++,dfs1(i,,),dfs2(i,i);}//注意连通图问题
get_SegmentTree(,,n);
cin>>m;
/*for(int i=1;i<=n;i++) cout<<b_value[i]<<" ";
cout<<endl;
for(int i=1;i<=n;i++) cout<<father[i]<<' ';
cout<<endl;*/
while(m --> ){//趋向于
_left=read(),_right=read();
if(group[_left]==group[_right]) printf("%d\n",pa(_left,_right));
else printf("-1\n");
}
return ;
}
【NOIP2013】货车运输的更多相关文章
- [Luogu 1967] NOIP2013 货车运输
[Luogu 1967] NOIP2013 货车运输 一年多前令我十分头大的老题终于可以随手切掉了- 然而我这码风又变毒瘤了,我也很绝望. 看着一年前不带类不加空格不空行的清纯码风啊,时光也好像回去了 ...
- NOIP2013 货车运输(最大生成树,倍增)
NOIP2013 货车运输(最大生成树,倍增) A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物,司机们想知道 ...
- NOIP2013 货车运输 (最大生成树+树上倍增LCA)
死磕一道题,中间发现倍增还是掌握的不熟 ,而且深刻理解:SB错误毁一生,憋了近2个小时才调对,不过还好一遍AC省了更多的事,不然我一定会疯掉的... 3287 货车运输 2013年NOIP全国联赛提高 ...
- NOIP2013 货车运输
3.货车运输 (truck.cpp/c/pas) [问题描述] A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货 ...
- Codevs3278[NOIP2013]货车运输
3287 货车运输 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description A 国有 ...
- 【洛谷P1967】[NOIP2013]货车运输
货车运输 题目链接 显然,从一点走到另一点的路径中,最小值最大的路径一定在它的最大生成树上 所以要先求出最大生成树,再在生成树上找最近公共祖先,同时求出最小值. #include<iostrea ...
- noip2013货车运输
P1967 货车运输 题目描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过 ...
- NOIP2013货车运输[lca&&kruskal]
题目描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多 ...
- [noip2013]货车运输(kruskal + 树上倍增)
描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过车辆限重的情况下,最多能运多 ...
- [luogu P1967][NOIp2013] 货车运输
题目描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多 ...
随机推荐
- tomcat 详解
首先搞清楚几个概念:Servlet容器与web容器.Servlet容器的主要任务是管理servlet的生命周期,而web容器更准确的说应该叫web服务器,它是来管理和部署web应用的.还有一种服务器叫 ...
- Java中方法与数组
1:方法(掌握) (1)方法:就是完成特定功能的代码块. 注意:在很多语言里面有函数的定义,而在Java中,函数被称为方法. (2)格式: 修饰符 返回值类型 方法名(参数类型 参数名1,参数类型 参 ...
- 《Java程序性能优化:让你的Java程序更快、更稳定》
Java程序性能优化:让你的Java程序更快.更稳定, 卓越网更便宜,不错的书吧
- Codeforces Round #249 (Div. 2)
A.水题. #include <cstdio> #include <iostream> #include <cstdlib> #include <cstrin ...
- 自定义UIPageControl
iphone的UIPageControl控件可以显示用户huan'dong滑动到的页码.但是里面的小点的颜色时默认的白色.如果背景也是白色的hu话,你就悲剧了.于是乎上网找了一些资料,找到了改变UIP ...
- android手机连接PC无法正常安装驱动
工作当中我们经常会遇到Android手机连接PC的时候无法正确安装驱动,或者安装失败.当然找到正确的驱动文件时首选的解决方案,如果正确的驱动文件依旧无法安装成功我们可以打开我的电脑-->属性-- ...
- Interview----最长连续乘积字串
题目描述: 给一个浮点数序列,取最大乘积连续子串的值,例如 -2.5,4,0,3,0.5,8,-1,则取出的最大乘积连续子串为3,0.5,8. 也就是说,上述数组中,3 0.5 8这3个数的乘积3*0 ...
- 【Tsinghua OJ】祖玛(Zuma)问题
描述 祖玛是一款曾经风靡全球的游戏,其玩法是:在一条轨道上初始排列着若干个彩色珠子,其中任意三个相邻的珠子不会完全同色.此后,你可以发射珠子到轨 道上并加入原有序列中.一旦有三个或更多同色的珠子变成相 ...
- JQuery基础DOM操作
DOM创建节点及节点属性 通过JavaScript可以很方便的获取DOM节点,从而进行一系列的DOM操作.但实际上一般开发者都习惯性的先定义好HTML结构,但这样就非常不灵活了. 试想下这样的情况:如 ...
- IOS 作业项目(4)步步完成 画图 程序(中续)
一,程序布局整理 前言://1,程序启动//2,程序流程框架//3,程序界面一致//4,程序界面功能, //这里只做页面的固定功能, //在首次创建界面时,我们会指定好固定事件触发前的固定方法 //至 ...