zoukankan      html  css  js  c++  java
  • 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
    ");
    117             continue;
    118         }
    119         int rt=LCA(x,y);
    120         if(rt==0){
    121             printf("-1
    ");
    122             continue;
    123         }
    124         int ans=max(mdis(x,rt),mdis(y,rt));
    125         printf("%d
    ",ans);
    126     }
    127     return 0;
    128 }
  • 相关阅读:
    Hibernate导致的内存溢出问题
    【转】class file has wrong version 50.0, should be 49.0错误
    修改SQL Server登陆认证方式
    [转]ExtJs中的Store
    70+优秀的前端工具
    书签
    十款好用的在线 CSS3 代码生成工具
    Web Uploader
    sass 在线编译工具之初学
    Web 开发中很有用的8款在线工具
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/5978148.html
Copyright © 2011-2022 走看看