• C++之路进阶——codevs3287(货车运输)


    3287 货车运输

    2013年NOIP全国联赛提高组

     时间限制: 1 s
     空间限制: 128000 KB
     题目等级 : 钻石 Diamond
     
    题目描述 Description

    A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路。每一条道路对车辆都有重量限制,简称限重。现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物。

    输入描述 Input Description

    第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道路。
    接下来 m 行每行 3 个整数 x、y、z,每两个整数之间用一个空格隔开,表示从 x 号城市到 y 号城市有一条限重为 z 的道路。注意:x 不等于 y,两座城市之间可能有多条道路。
    接下来一行有一个整数 q,表示有 q 辆货车需要运货。
    接下来 q 行,每行两个整数 x、y,之间用一个空格隔开,表示一辆货车需要从 x 城市运输货物到 y 城市,注意:x 不等于 y。

    输出描述 Output Description

    输出共有 q 行,每行一个整数,表示对于每一辆货车,它的最大载重是多少。如果货车不能到达目的地,输出-1。

    样例输入 Sample Input

    4 3 
    1 2 4 
    2 3 3 
    3 1 1 
    3
    1 3 
    1 4 
    1 3

    样例输出 Sample Output

    3
    -1
    3

    数据范围及提示 Data Size & Hint

    对于 30%的数据,0 < n < 1,000,0 < m < 10,000,0 < q < 1,000; 
    对于 60%的数据,0 < n < 1,000,0 < m < 50,000,0 < q < 1,000; 
    对于 100%的数据,0 < n < 10,000,0 < m < 50,000,0 < q < 30,000,0 ≤ z ≤ 100,000。

    题解:

       树上倍增LCA...

    代码:

        

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<vector>
      4 #include<algorithm>
      5 #define maxn 10010
      6 
      7 using namespace std;
      8  
      9 vector<int> p[maxn],c[maxn]; 
     10 
     11 struct node
     12    {
     13        int l,r,v;
     14    }s[50010];
     15    
     16 struct ss
     17     {
     18       int p;     
     19       int c;         
     20      } f[maxn][50];
     21      
     22 bool cmp(node a,node b)
     23      {
     24          return a.v>b.v;
     25      }
     26 int deep[maxn],n,m,fa[maxn],kg[maxn];
     27 
     28 void getree(int k,int d)
     29    {
     30         deep[k]=d;
     31         kg[k]=1;
     32      for (int i=1;(1<<i)<=deep[k];i++)
     33          {
     34              f[k][i].p=f[f[k][i-1].p][i-1].p;
     35              f[k][i].c=min(f[k][i-1].c,f[f[k][i-1].p][i-1].c);
     36              }    
     37     for (int i=0;i<p[k].size();i++)
     38               if (!deep[p[k][i]])
     39                {
     40                   f[p[k][i]][0].p=k;
     41                   f[p[k][i]][0].c=c[k][i];
     42                   getree(p[k][i],d+1);       
     43                    }         
     44         }     
     45 int lca(int a,int b)
     46    {
     47         if (deep[a]<deep[b]) swap(a,b);
     48           int t=deep[a]-deep[b];
     49           int ans=0x7fffffff; 
     50             for (int i=0;i<=20;i++) 
     51                 if ((1<<i)&t) {
     52                 ans=min(f[a][i].c,ans);
     53                 a=f[a][i].p; 
     54             }
     55             for (int i=20;i>=0;i--)
     56               if (f[a][i].p!=f[b][i].p)
     57                  {
     58                      ans=min(f[b][i].c,ans);
     59                      ans=min(f[a][i].c,ans);
     60                     a=f[a][i].p;
     61                     b=f[b][i].p;        
     62                   }
     63         if (a==b) return ans;
     64          else return min(f[a][0].c,min(f[b][0].c,ans));                         
     65             }
     66 
     67 int find(int x)
     68    {
     69         if (fa[x]==x) return x;
     70            fa[x]=find(fa[x]);
     71            return fa[x];
     72                }            
     73             
     74 void init()
     75   {
     76     scanf("%d%d",&n,&m);     
     77       for (int i=0;i<m;i++)
     78         scanf("%d%d%d",&s[i].l,&s[i].r,&s[i].v);         
     79     sort(s+0,s+m,cmp);    
     80     for (int i=0;i<=n;i++)
     81        fa[i]=i;      
     82    }
     83 int  main()
     84    {
     85        init();
     86        for (int i=0;i<m;i++)
     87           {
     88                  int pp=find(s[i].l);
     89                  int qq=find(s[i].r);
     90                 if (pp!=qq)
     91                    {
     92                        fa[pp]=qq;
     93                        p[s[i].l].push_back(s[i].r);
     94                 c[s[i].l].push_back(s[i].v);
     95                 p[s[i].r].push_back(s[i].l);
     96                 c[s[i].r].push_back(s[i].v);
     97                    }
     98           }
     99     for (int i=1;i<=n;i++)
    100        if (!kg[i])    getree(i,1);  
    101         scanf("%d",&m); 
    102     for (int i=0;i<m;i++)
    103       {
    104             int x,y;
    105           scanf("%d%d",&x,&y);
    106           if (find(x)!=find(y)) printf("-1
    ");
    107            else  printf("%d
    ",lca(x,y));    
    108             }      
    109      return 0;        
    110         }    
  • 相关阅读:
    生手和FinallyJane一起学习ASP.NET
    使用eclipse 初学java
    关于C#中用access做数据库,使用like语句的问题(转)
    VSS (Visual Source Safe 2005) 用法详解(转)
    mysql 字符集问题之我见
    mysqli的预处理功能使用
    兼容IE和Firefox
    linux下netsnmp 已经安装,为什么没有 snmpwalk和snmpget
    ? PHP WBEM
    安装cacti时提示错误
  • 原文地址:https://www.cnblogs.com/grhyxzc/p/5132717.html
Copyright © 2020-2023  润新知