【CODEVS 3287】【NOIP2013】火车运输
http://codevs.cn/problem/3287/
题目描述
国有
座城市,编号从
到
,城市之间有
条双向道路。每一条道路对车辆都有重
量限制,简称限重。现在有 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的
情况下,最多能运多重的货物。
输入格式
输入文件第一行有两个用一个空格隔开的整数 , 表示
国有
座城市和
条道
路。
接下来 行每行
个整数
,每两个整数之间用一个空格隔开,表示从
号城市
到 号城市有一条限重为
的道路。注意:
不等于
,两座城市之间可能有多条道路。
接下来一行有一个整数 ,表示有
辆货车需要运货。
接下来 行,每行两个整数
、
,之间用一个空格隔开,表示一辆货车需要从
城市
运输货物到 城市,注意:
不等于
。
输出格式
输出共有 行,每行一个整数,表示对于每一辆货车,它的最大载重是多少。如果货
车不能到达目的地,输出 。
输入样例
4 3
1 2 4
2 3 3
3 1 1
3
1 3
1 4
1 3
输出样例
3
-1
3
数据范围
题解
可以证明最优路径一定在最大生成树(森林)上,于是题目便转化为,询问森林中两点路径上边权最小值,连通性用并查集判断即可。
对于一棵树上的一次询问,可以用倍增的方法解决。
表示点
向上
步到达的结点
表示点
向上
步的路径中的边权最小值
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#define N 10005
#define M 50005
#define depth 21
using namespace std; int n,m,q,cnt,tot,ans;
int f[N],last[N],dep[N];
int anc[N][],g[N][];
struct hh
{int to,next,w;}e[M<<];
struct hhh
{int l,r,w;}line[M<<];
bool cmp(hhh a,hhh b){return a.w>b.w;}
int read()
{
int ret=;char c=getchar();
while(!isdigit(c))c=getchar();
while(isdigit(c)){ret=(ret<<)+(ret<<)+c-'';c=getchar();}
return ret;
}
void add(int a,int b,int w)
{
e[++tot].to=b;
e[tot].next=last[a];
e[tot].w=w;
last[a]=tot;
}
void bfs(int root)
{
int i,j,now;
stack<int> s;
s.push(root);dep[root]=;
for(i=;i<depth;i++) anc[root][i]=root;
while(!s.empty())
{
now=s.top();s.pop();
if(now!=root)
for(i=;i<depth;i++)
{
anc[now][i]=anc[anc[now][i-]][i-];
g[now][i]=min(g[now][i-],g[anc[now][i-]][i-]);
}
for(i=last[now];i;i=e[i].next)
if(!dep[e[i].to])
{
anc[e[i].to][]=now;
dep[e[i].to]=dep[now]+;
g[e[i].to][]=e[i].w;
s.push(e[i].to);
}
}
}
void swim(int& x,int h)
{
int i;
for(i=;h;i++)
{
if(h&) x=anc[x][i];
h>>=;
}
}
int getlca(int x,int y)
{
int i,j;
if(dep[x]<dep[y]) swap(x,y);
swim(x,dep[x]-dep[y]);
if(x==y) return x;
while(true)
{
for(i=;anc[x][i]!=anc[y][i];i++);
if(!i) return anc[x][];
x=anc[x][i-];y=anc[y][i-];
}
}
int query(int x,int y)
{
int i,ret=,h;
h=dep[y]-dep[x];
for(i=depth;i>=;i--)
if((<<i)<=h)
{
h-=(<<i);
ret=min(ret,g[y][i]);
y=anc[y][i];
}
return ret;
}
int find(int x){return f[x]==x?x:f[x]=find(f[x]);}
int main()
{
int i,j,u,v,w,fx,fy,lca;
n=read();m=read();
for(i=;i<=m;i++)
line[i].l=read(),line[i].r=read(),line[i].w=read();
sort(line+,line++m,cmp);
for(i=;i<=n;i++) f[i]=i;
for(i=;i<=m;i++)
{
u=line[i].l;v=line[i].r;w=line[i].w;
fx=find(u);fy=find(v);
if(fx!=fy)
{
f[fx]=fy;cnt++;
add(u,v,w);add(v,u,w);
if(cnt==n-) break;
}
}
for(i=;i<=n;i++)
for(j=;j<depth;j++)
g[i][j]=;
bfs();
q=read();
for(i=;i<=q;i++)
{
u=read();v=read();
if(find(u)!=find(v)){puts("-1");continue;}
lca=getlca(u,v);
ans=min(query(lca,u),query(lca,v));
printf("%d\n",ans);
}
return ;
}
【CODEVS 3287】【NOIP2013】火车运输的更多相关文章
- [Luogu 1967] NOIP2013 货车运输
[Luogu 1967] NOIP2013 货车运输 一年多前令我十分头大的老题终于可以随手切掉了- 然而我这码风又变毒瘤了,我也很绝望. 看着一年前不带类不加空格不空行的清纯码风啊,时光也好像回去了 ...
- NOIP2013 货车运输(最大生成树,倍增)
NOIP2013 货车运输(最大生成树,倍增) A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物,司机们想知道 ...
- [NOIP2013提高组] CODEVS 3287 火车运输(MST+LCA)
一开始觉得是网络流..仔细一看应该是最短路,再看数据范围..呵呵不会写...这道题是最大生成树+最近公共祖先.第一次写..表示各种乱.. 因为要求运输货物质量最大,所以路径一定是在最大生成树上的.然后 ...
- codevs 3287 货车运输 NOIP2013提高组
题目链接:http://codevs.cn/problem/3287/ 题解: 和bzoj3732一毛一样,只不过是找最大生成树和最小值罢了,具体参见我的bzoj3732的博客 #include< ...
- Codevs 3287 货车运输 2013年NOIP全国联赛提高组(带权LCA+并查集+最大生成树)
3287 货车运输 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 传送门 题目描述 Description A 国有 n 座 ...
- Codevs 3287 货车运输 == 洛谷P1967
3287 货车运输 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description A 国有 n 座城市,编 ...
- Codevs 3287 货车运输
题目描述 Description A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过 ...
- 货车运输(codevs 3287)
题目描述 Description A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过 ...
- NOIP2013 DAY2 T3火车运输
传送门 题目描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况 ...
随机推荐
- Linux监控工具 (Linux Monitor Tools)
最近发现几个好用的工具,顺便总结下. Zabbix和Nagios属于重量级,企业级Service procps-ng: top, free, ps, pgrep, vmstat ... sysstat ...
- BugFixed
- Oracle数据库入门——pctfree和pctused详解
一.建立表时候,注意PCTFREE参数的作用 PCTFREE:为一个块保留的空间百分比,表示数据块在什么情况下可以被insert,默认是10,表示当数据块的可用空间低于10%后,就不可以被insert ...
- Qt编写自定义控件一开关按钮
从2010年进入互联网+智能手机时代以来,各种各样的APP大行其道,手机上面的APP有很多流行的元素,开关按钮个人非常喜欢,手机QQ.360卫士.金山毒霸等,都有很多开关控制一些操作,在Qt widg ...
- 个性化EDM数据营销的三大提醒
EDM数据营销行业已经进入个性化时代.但是怎样实现个性化仍然是一个重大课题.国内领先的智能化邮件营销服务商Focussend一直致力于探索和研究邮件营销领域的先进知识和做法,旨在为企业和个人提供更多有 ...
- 从头构建自己的Linux系统
2012-09-10 在博文“Linux系统启动过程分析”中我们了解了linux系统的启动流程,今天我们就来手动一步一步从头来构建一个最小的linux系统,然后用模拟器将其加载起来.常见 ...
- 【转载】JDBC连接各种数据库的字符串
oracle driverClass:oracle.jdbc.driver.OracleDriver url:jdbc:oracle:thin:@127.0.0.1:1521:dbname ...
- Android应用如何支持屏幕多尺寸多分辨率问题
作为Android应用程序开发者都知道android是一个“碎片化”的世界.多种系统版本.多种尺寸.多种分辨率.多种机型,还有不同的厂商定制的不同ROM,你开发的应用会在不可预期的手机上报错.这给开发 ...
- Linux下查看tcp连接数及状态
netstat -n | awk ‘/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}’ TIME_WAIT 8947FIN_WAIT1 15FIN_W ...
- mysql 语句case when
CREATE TABLE `lee` (`id` int(10) NOT NULL AUTO_INCREMENT, `name` char(20) DEFAULT NULL, `birthday` d ...