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. SharedPreference注册OnSharedPreferenceChangeListener一直无法回调问题

    注册代码如下: SharedPreferences sp = getSharedPreferences("AndroidDemo", Context.MODE_PRIVATE); ...

  2. PowerShell实现文件下载(类wget)

    对Linux熟悉的读者可能会对Linux通过wget下载文件有印象,这个工具功能很强大,在.NET环境下提到下载文件大多数人熟悉的是通过System.Net.WebClient进行下载,这个程序集能实 ...

  3. Nhibernate基础

    Nhibernate(英文冬眠的意思) 常用方法 Contains Evict Clear  在 NHibernate 中一切必须是 Virtual 的吗? http://www.cnblogs.co ...

  4. [转载]堆排序(HeapSort) Java实现

    堆排序的思想是利用数据结构--堆.具体的实现细节: 1. 构建一个最大堆.对于给定的包含有n个元素的数组A[n],构建一个最大堆(最大堆的特性是,某个节点的值最多和其父节点的值一样大.这样,堆中的最大 ...

  5. sql:pivot unpivot

    pivot  行转列 unpivot  列转行 源码跑步起来 这是能跑起来的 源码转自 http://www.cnblogs.com/zhangzt/archive/2010/07/29/178782 ...

  6. 非常简单实用的Python HTTP服务

    在做分布式系统应用的时候经常在测试环境上传一个包,或者干嘛的,公司的服务器比较bug,只给ldap权限,每次只能scp到自己的个人目录下,然后才能进到公共账号下去cp,比较麻烦.这时候如果你需要一个简 ...

  7. Android 自定义Drawable

    1.使用BitmapShader实现图片圆角 public class CornerDrawable extends Drawable { private Paint mPaint; private ...

  8. php 类文件加载 Autoloader

    做习惯了编译语言,转到php 使用 php的面向对象开发时候遇见一个挺别扭的问题.在Php中引入对象 后 在调用过程中还需要将对象所在的php文件 require 到当前php文件 目前代码结构 in ...

  9. Jenkins+Maven+SVN快速搭建持续集成环境(转)

    Jenkins是一个可扩展的持续集成引擎,Jenkins非常易于安装和配置,简单易用,下面看看我们是如何几分钟就快速搭建一个持续集成环境吧. 假设我们目前已经有2个maven项目:entities(J ...

  10. SQL 解锁表

    http://www.cnblogs.com/chjf2008/archive/2012/11/21/2780787.html 最主要是找到最近使用工具或者应用连接过数据库的进程,关掉它就可以了.