CodeVs1519 过路费

题目描述 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,顺便倍增找路上最大值。

  1 /*by SilverN*/
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<cmath>
  7 using namespace std;
  8 const int mxn=300010;
  9 //bas
 10 int n,m;
 11 //edge
 12 struct li{
 13     int u,v,dis;
 14 }line[mxn];
 15 int cmp(li a,li b){
 16     return a.dis<b.dis;
 17 }
 18 struct node{
 19     int v,dis;
 20     int next;
 21 }e[mxn];
 22 int hd[mxn],cnt;
 23 //
 24 //bc
 25 int fa[mxn];
 26 void init(){
 27     for(int i=1;i<=n;i++)fa[i]=i;
 28 }
 29 int find(int x){
 30     if(fa[x]==x)return x;
 31     return fa[x]=find(fa[x]);
 32 }
 33 //tree
 34 int dep[mxn];
 35 int f[mxn][20];
 36 int w[mxn][20];
 37 //
 38 void add_edge(int u,int v,int dis){
 39     e[++cnt].next=hd[u];e[cnt].dis=dis;e[cnt].v=v;hd[u]=cnt;
 40     e[++cnt].next=hd[v];e[cnt].dis=dis;e[cnt].v=u;hd[v]=cnt;
 41 }
 42 void kruskal(){
 43     int i,j;
 44     int tot=1;
 45     for(i=1;i<=m;i++){
 46         int x=find(line[i].u),y=find(line[i].v);
 47         if(x!=y){
 48             fa[x]=y;
 49             tot++;
 50             add_edge(line[i].u,line[i].v,line[i].dis);
 51         }
 52     }
 53 }
 54 void dfs(int u,int fafa){
 55     dep[u]=dep[fafa]+1;
 56     f[u][0]=fafa;
 57     int i,j;
 58     for(i=hd[u];i;i=e[i].next){
 59         int v=e[i].v;
 60         if(v==fafa)continue;
 61         w[v][0]=e[i].dis;
 62         dfs(v,u);
 63     }
 64     return;
 65 }
 66 void solve(){
 67     int i,j;
 68     for(i=1;i<=n;i++)if(!dep[i]){
 69         dep[i]=1;
 70         dfs(i,0);
 71     }
 72     for(j=1;j<=18;j++)
 73       for(i=1;i<=n;i++){
 74           f[i][j]=f[f[i][j-1]][j-1];
 75       }
 76     for(j=1;j<=18;j++)
 77       for(i=1;i<=n;i++){
 78         w[i][j]=max(w[i][j-1],w[f[i][j-1]][j-1]);
 79       }
 80
 81 }
 82 int LCA(int x,int y){
 83     if(dep[x]<dep[y])swap(x,y);
 84     int i;
 85     for(i=18;i>=0;i--)if(dep[f[x][i]]>=dep[y])x=f[x][i];
 86     if(x==y)return x;
 87     for(i=18;i>=0;i--)
 88         if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
 89     return f[x][0];
 90 }
 91 int mdis(int x,int rt){
 92     int d=dep[x]-dep[rt];
 93     int res=0;
 94     for(int i=18;i>=0;i--)
 95         if((d>>i)&1){
 96             res=max(res,w[x][i]);
 97             x=f[x][i];
 98         }
 99     return res;
100 }
101 int main(){
102     scanf("%d%d",&n,&m);
103     int i,j;
104     int u,v,dis;
105     for(i=1;i<=m;i++) scanf("%d%d%d",&line[i].u,&line[i].v,&line[i].dis);
106     sort(line+1,line+m+1,cmp);
107     init();
108     kruskal();
109     solve();
110     int q;
111     scanf("%d",&q);
112     int x,y;
113     for(i=1;i<=q;i++){
114         scanf("%d%d",&x,&y);
115         if(find(x)!=find(y)){
116             printf("-1\n");
117             continue;
118         }
119         int rt=LCA(x,y);
120         if(rt==0){
121             printf("-1\n");
122             continue;
123         }
124         int ans=max(mdis(x,rt),mdis(y,rt));
125         printf("%d\n",ans);
126     }
127     return 0;
128 }
时间: 2024-10-11 00:58:05

CodeVs1519 过路费的相关文章

习题:过路费(kruskal+并查集+LCA)

过路费  [问题描述]在某个遥远的国家里,有 n 个城市.编号为 1,2,3,…,n.这个国家的政府修 建了 m 条双向道路,每条道路连接着两个城市.政府规定从城市 S 到城市 T 需 要收取的过路费为所经过城市之间道路长度的最大值.如:A 到 B 长度为 2,B 到 C 长度为 3,那么开车从 A 经过 B 到 C 需要上交的过路费为 3. 佳佳是个做生意的人,需要经常开车从任意一个城市到另外一个城市,因此 他需要频繁地上交过路费,由于忙于做生意,所以他无时间来寻找交过路费最低 的行驶路线.然

1774: [Usaco2009 Dec]Toll 过路费

1774: [Usaco2009 Dec]Toll 过路费 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 263  Solved: 154[Submit][Status][Discuss] Description 跟所有人一样,农夫约翰以着宁教我负天下牛,休叫天下牛负我的伟大精神,日日夜夜苦思生 财之道.为了发财,他设置了一系列的规章制度,使得任何一只奶牛在农场中的道路行走,都 要向农夫约翰上交过路费. 农场中由N(1 <= N <= 250)片

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

/*codevs 1519 过路费 最小生成树+倍增*/ #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 100010 #define inf 0x3f3f3f3 using namespace std; int n,m,q,num,head[maxn],fa[maxn][25],mx[maxn][25],c[maxn],father

FZU 2082 过路费 (树链剖分)边权

Problem 2082 过路费 Accept: 322    Submit: 1101 Time Limit: 1000 mSec    Memory Limit : 32768 KB Problem Description 有n座城市,由n-1条路相连通,使得任意两座城市之间可达.每条路有过路费,要交过路费才能通过.每条路的过路费经常会更新,现问你,当前情况下,从城市a到城市b最少要花多少过路费. Input 有多组样例,每组样例第一行输入两个正整数n,m(2 <= n<=50000,1&

Cocos2d-x 3.2 大富翁游戏项目开发-第十六部分 相连地块缴纳过路费

当走到其他角色的地块时,根据当前地块是否连片,连片的话统一计算需要缴纳的过路费,连片的计算方式,是各个地块过路费总和. 首先获取当前行走角色路过的地块的x y坐标(Land layer层的坐标),然后获取角色的坐标(GL的坐标,需要转换成map中的坐标), 然后对这2个坐标值进行横向和纵向比较. 如图A位置:以寻找左边地块的方法为例分析 1. 把角色A坐标转换成map中的坐标 2. 把当前0号地块的sprite对象放入容器中,以便后面播放淡入淡出的动画 3. 0号地块x坐标同角色A的map坐标的

usaco 过路费 Cow Toll Paths, 2009 Dec

Description 翰家有 N 片草地,编号为 1 到 N ,彼此之间由 M 条双向道路连接,第 i 条道路连接了 Ai 和Bi,两片草地之间可能有多条道路,但没有道路会连接同一片草地,现有的道路可以保证任意两片草 地都是连通的. 有一天,约翰宣布奶牛走路要收过路费,只要奶牛走过第 i 条道路,就要收费 Li 元.此外,约 翰还要求每头奶牛购买牌照,他为每片草地设置了牌照标准,如果奶牛购买的牌照价格低于某片草地 的标准,她将被禁止进入那片草地.第 i 片草地的牌照标准为 Ci. 新政策一出,

FZU 2082 过路费

过路费 Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on FZU. Original ID: 208264-bit integer IO format: %I64d      Java class name: Main 有n座城市,由n-1条路相连通,使得任意两座城市之间可达.每条路有过路费,要交过路费才能通过.每条路的过路费经常会更新,现问你,当前情况下,从城市a到城市b最少要花多少过路费. Inpu

1519 过路费

1519 过路费 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 大师 Master 题解 题目描述 Description 在某个遥远的国家里,有 n个城市.编号为 1,2,3,…,n.这个国家的政府修建了m 条双向道路,每条道路连接着两个城市.政府规定从城市 S 到城市T需要收取的过路费为所经过城市之间道路长度的最大值.如:A到B长度为 2,B到C 长度为3,那么开车从 A经过 B到C 需要上交的过路费为 3.    佳佳是个做生意的人,需要经常开车从任意一个城市到另外一个

[Usaco2009 Dec]Toll 过路费

题面: 跟所有人一样,农夫约翰以着宁教我负天下牛,休教天下牛负我(原文:宁我负人,休教人负我)的伟大精神,日日夜夜苦思生财之道.为了发财,他设置了一系列的规章制度,使得任何一只奶牛在农场中的道路行走,都要向农夫约翰上交过路费. 农场中由N(1 <= N <= 250)片草地(标号为1到N),并且有M(1 <= M <= 10000)条双向道路连接草地A_j和B_j(1 <= A_j <= N; 1 <= B_j <= N).奶牛们从任意一片草地出发可以抵达任