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\n");
107            else  printf("%d\n",lca(x,y));    
108             }      
109      return 0;        
110         }