首页 > 代码库 > CodeVs1519 过路费

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 }

 

CodeVs1519 过路费