题目描述 Description

在某个遥远的国家里,有 n个城市。编号为 1,2,3,…,n。这个国家的政府修建了m 条双向道路,每条道路连接着两个城市。政府规定从城市 S 到城市T需要收取的过路费为所经过城市之间道路长度的最大值。如:A到B长度为 2,B到C 长度为3,那么开车从 A经过 B到C 需要上交的过路费为 3。
    佳佳是个做生意的人,需要经常开车从任意一个城市到另外一个城市,因此他需要频繁地上交过路费,由于忙于做生意,所以他无时间来寻找交过路费最低的行驶路线。然而, 当他交的过路费越多他的心情就变得越糟糕。 作为秘书的你,需要每次根据老板的起止城市,提供给他从开始城市到达目的城市,最少需要上交多少过路费。

输入描述 Input Description

第一行是两个整数 n 和m,分别表示城市的个数以及道路的条数。 
    接下来 m 行,每行包含三个整数 a,b,w(1≤a,b≤n,0≤w≤10^9),表示a与b之间有一条长度为 w的道路。
    接着有一行为一个整数 q,表示佳佳发出的询问个数。 
    再接下来 q行,每一行包含两个整数 S,T(1≤S,T≤n,S≠T), 表示开始城市S 和目的城市T。

输出描述 Output Description

输出共q行,每行一个整数,分别表示每个询问需要上交的最少过路费用。输入数据保证所有的城市都是连通的。

样例输入 Sample Input

4 5 
1 2 10 
1 3 20 
1 4 100 
2 4 30 
3 4 10 

1 4 
4 1

样例输出 Sample Output

20 
20

数据范围及提示 Data Size & Hint

对于 30%的数据,满足 1≤ n≤1000,1≤m≤10000,1≤q≤100; 
对于 50%的数据,满足 1≤ n≤10000,1≤m≤10000,1≤q≤10000; 
对于 100%的数据,满足 1≤ n≤10000,1≤m≤100000,1≤q≤10000;

@货车运输

先求出最小生成树,再求LCA,顺便倍增找路上最大值。

 /*by SilverN*/
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
const int mxn=;
//bas
int n,m;
//edge
struct li{
int u,v,dis;
}line[mxn];
int cmp(li a,li b){
return a.dis<b.dis;
}
struct node{
int v,dis;
int next;
}e[mxn];
int hd[mxn],cnt;
//
//bc
int fa[mxn];
void init(){
for(int i=;i<=n;i++)fa[i]=i;
}
int find(int x){
if(fa[x]==x)return x;
return fa[x]=find(fa[x]);
}
//tree
int dep[mxn];
int f[mxn][];
int w[mxn][];
//
void add_edge(int u,int v,int dis){
e[++cnt].next=hd[u];e[cnt].dis=dis;e[cnt].v=v;hd[u]=cnt;
e[++cnt].next=hd[v];e[cnt].dis=dis;e[cnt].v=u;hd[v]=cnt;
}
void kruskal(){
int i,j;
int tot=;
for(i=;i<=m;i++){
int x=find(line[i].u),y=find(line[i].v);
if(x!=y){
fa[x]=y;
tot++;
add_edge(line[i].u,line[i].v,line[i].dis);
}
}
}
void dfs(int u,int fafa){
dep[u]=dep[fafa]+;
f[u][]=fafa;
int i,j;
for(i=hd[u];i;i=e[i].next){
int v=e[i].v;
if(v==fafa)continue;
w[v][]=e[i].dis;
dfs(v,u);
}
return;
}
void solve(){
int i,j;
for(i=;i<=n;i++)if(!dep[i]){
dep[i]=;
dfs(i,);
}
for(j=;j<=;j++)
for(i=;i<=n;i++){
f[i][j]=f[f[i][j-]][j-];
}
for(j=;j<=;j++)
for(i=;i<=n;i++){
w[i][j]=max(w[i][j-],w[f[i][j-]][j-]);
} }
int LCA(int x,int y){
if(dep[x]<dep[y])swap(x,y);
int i;
for(i=;i>=;i--)if(dep[f[x][i]]>=dep[y])x=f[x][i];
if(x==y)return x;
for(i=;i>=;i--)
if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
return f[x][];
}
int mdis(int x,int rt){
int d=dep[x]-dep[rt];
int res=;
for(int i=;i>=;i--)
if((d>>i)&){
res=max(res,w[x][i]);
x=f[x][i];
}
return res;
}
int main(){
scanf("%d%d",&n,&m);
int i,j;
int u,v,dis;
for(i=;i<=m;i++) scanf("%d%d%d",&line[i].u,&line[i].v,&line[i].dis);
sort(line+,line+m+,cmp);
init();
kruskal();
solve();
int q;
scanf("%d",&q);
int x,y;
for(i=;i<=q;i++){
scanf("%d%d",&x,&y);
if(find(x)!=find(y)){
printf("-1\n");
continue;
}
int rt=LCA(x,y);
if(rt==){
printf("-1\n");
continue;
}
int ans=max(mdis(x,rt),mdis(y,rt));
printf("%d\n",ans);
}
return ;
}

CodeVs1519 过路费的更多相关文章

  1. [Codevs1519]过路费解题报告|最小生成树|LCA

    在某个遥远的国家里,有 n个城市.编号为 1,2,3,…,n.这个国家的政府修建了m 条双向道路,每条道路连接着两个城市.政府规定从城市 S 到城市T需要收取的过路费为所经过城市之间道路长度的最大值. ...

  2. codevs1519 过路费(最小生成树+LCA)

    1519 过路费  时间限制: 1 s  空间限制: 256000 KB  题目等级 : 大师 Master     题目描述 Description 在某个遥远的国家里,有 n个城市.编号为 1,2 ...

  3. FZU Problem 2082 过路费 树链剖分

    Problem 2082 过路费    Problem Description 有n座城市,由n-1条路相连通,使得任意两座城市之间可达.每条路有过路费,要交过路费才能通过.每条路的过路费经常会更新, ...

  4. Uva 10537 过路费

    题目链接:http://vjudge.net/contest/143062#problem/C 题意: 给定一个无向图,大写字母是城市,小写字母是村庄,经过城市交过路费为当前货物的%5,路过村庄固定交 ...

  5. Floyd | | jzoj[1218] | | [Usaco2009 Dec]Toll 过路费 | | BZOJ 1774 | | 我也不知道该怎么写

    写在前面:老师说这一道题是神题,事实上确实如此,主要是考察对Floyd的理解 ******************************题目.txt************************* ...

  6. Fzu Problem 2082 过路费 LCT,动态树

    题目:http://acm.fzu.edu.cn/problem.php?pid=2082 Problem 2082 过路费 Accept: 528    Submit: 1654Time Limit ...

  7. codevs 1519 过路费 最小生成树+倍增

    /*codevs 1519 过路费 最小生成树+倍增*/ #include<iostream> #include<cstdio> #include<cstring> ...

  8. FZU 2082 过路费(树链剖分)

    FZU 2082 过路费 题目链接 树链抛分改动边的模板题 代码: #include <cstdio> #include <cstring> #include <vect ...

  9. 1774: [Usaco2009 Dec]Toll 过路费

    1774: [Usaco2009 Dec]Toll 过路费 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 263  Solved: 154[Submit ...

随机推荐

  1. [转]彻底明确怎样设置minSdkVersion和targetSdkVersion

    minSdkVersion和targetSdkVersion相信非常多人都不太理解.我在网上也看了很多关于这两者差别的文章,感觉说的都非常模糊.直到我在stackOverFlow看到Android M ...

  2. CF749C Voting

    题目链接: http://codeforces.com/problemset/problem/749/C 题目大意: 共有n个人,编号为1~n.他们每个人属于且仅属于R阵营或N阵营中的一个.现在他们要 ...

  3. Design Compiler 综合

    综合(synthesis) = 转换(translation) + 优化(logic optimization) + 映射(gate mapping): 转换阶段将HDL语言描述的电路用门级逻辑实现. ...

  4. Python 中print 和return 的区别

    1.print() print()函数的作用是输出数据到控制台,就是打印在你能看到的界面上. 2.return return语句[表达式]退出函数,选择性地向调用方返回一个表达式.不带参数值的retu ...

  5. uva1660 Cable TV Network

    点连通度:最少删除几个点使图不连通 拆点就变成了最小割 注意编号.画图就知道u’连v,v’连u. 技巧:不需要枚举S,T.固定S,枚举T即可 这种输入很烦, scanf(" (%d,%d)& ...

  6. js 数组过滤 filter

    let res = this.list.filter(item => routeEqual(this.currentRouteObj, item) || item.name === this.$ ...

  7. #PHP#微信支付 第二篇 JSAPI 调用统一下单接口获取预支付交易数据

    上一篇讲到成功获取 openid,本篇要调用微信统一接口创建预支付交易单,并获取到相关数据,以便(后边)在微信内调起H5支付 第三步,调用微信统一下单接口创建预支付交易单 微信统一下单API是微信支付 ...

  8. 如何改android device monitor文件的权限

    adb.exe在c/Android/platform-tools目录下,在这个目录下打开终端,然后adb shell,然后su http://blog.csdn.net/u012719153/arti ...

  9. mongodb windows 开机启动

    1)新建存放db E:\mongodb\data\db 2)新建日志文件 E:\mongodb\logs\log.txt 3)管理员运行Cmd 4)CD mongodb安装路径 5)运行命令 mong ...

  10. java 定时任务-servlet

    在web.xml中配置监听类. <listener> <listener-class>com.skin.generate.action.TaskManager</list ...