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】火车运输的更多相关文章

  1. [Luogu 1967] NOIP2013 货车运输

    [Luogu 1967] NOIP2013 货车运输 一年多前令我十分头大的老题终于可以随手切掉了- 然而我这码风又变毒瘤了,我也很绝望. 看着一年前不带类不加空格不空行的清纯码风啊,时光也好像回去了 ...

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

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

  3. [NOIP2013提高组] CODEVS 3287 火车运输(MST+LCA)

    一开始觉得是网络流..仔细一看应该是最短路,再看数据范围..呵呵不会写...这道题是最大生成树+最近公共祖先.第一次写..表示各种乱.. 因为要求运输货物质量最大,所以路径一定是在最大生成树上的.然后 ...

  4. codevs 3287 货车运输 NOIP2013提高组

    题目链接:http://codevs.cn/problem/3287/ 题解: 和bzoj3732一毛一样,只不过是找最大生成树和最小值罢了,具体参见我的bzoj3732的博客 #include< ...

  5. Codevs 3287 货车运输 2013年NOIP全国联赛提高组(带权LCA+并查集+最大生成树)

    3287 货车运输 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 传送门 题目描述 Description A 国有 n 座 ...

  6. Codevs 3287 货车运输 == 洛谷P1967

    3287 货车运输 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description A 国有 n 座城市,编 ...

  7. Codevs 3287 货车运输

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

  8. 货车运输(codevs 3287)

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

  9. NOIP2013 DAY2 T3火车运输

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

随机推荐

  1. wpf xaml inlines

    string testBold = "<Bold>Sync Now</Bold>";           var ele = System.Windows. ...

  2. struts2:遍历自定义字符串数组,遍历Action实例所引用对象中的数组

    在struts2:OGNL表达式,遍历List.Map集合:投影的使用一文中已经讲述了OGNL遍历List.Map集合等功能. 本文简单写一个遍历数组的示范程序. 1. 遍历自定义字符串数组 < ...

  3. Hibernate缓存原理与策略 Hibernate缓存原理:

    Hibernate缓存原理: 对于Hibernate这类ORM而言,缓存显的尤为重要,它是持久层性能提升的关键.简单来讲Hibernate就是对JDBC进行封装,以实现内部状态的管理,OR关系的映射等 ...

  4. Tips for thrift

    Introduction I have designed and developed game servers successfully with thrift (http://thrift.apac ...

  5. 10个你必须掌握的超酷VI命令技巧

    摘要:大部分Linux开发者对vi命令相当熟悉,可是遗憾的是,大部分开发者都只能掌握一些最常用的Linux vi命令,下面介绍的10个vi命令虽然很多不为人知,但是在实际应用中又能让你大大提高效率. ...

  6. 转 如何理解 重要性采样(importance sampling)

    分类: 我叫学术帖2011-03-25 13:22 3232人阅读 评论(4) 收藏 举报 图形 重要性采样是非常有意 思的一个方法.我们首先需要明确,这个方法是基于采样的,也就是基于所谓的蒙特卡洛法 ...

  7. Android 使用NDK编译sipdroid Library

    sipdroid是一款开源的运行于Android平台上的voip,目前支持音频和视频通话: 项目拖管地址:http://code.google.com/p/sipdroid/ 下载源代码,导入ecli ...

  8. Warning: Multiple build commands for output file /xxx

    xcode中 有时候会报一个警告: [WARN]Warning: Multiple build commands for output file /xxx 要解决这个问题很简单: 1.选择你的工程 2 ...

  9. 注意啦!10 个你需要了解的 Linux 网络和监控命令

    下面列出来的10个基础的每个Linux用户都应该知道的网络和监控命令.网络和监控命令类似于这些:hostname, ping, ifconfig, iwconfig, netstat, nslooku ...

  10. debian系统root用户登录

    Debian默认不允许root登录,所以修改之. 让Debian以root登录 1).首先修改gdm3的设定文件(/etc/gdm3/deamon.conf),在[security]字段后面追加如下一 ...