zoukankan      html  css  js  c++  java
  • 【洛谷P1967】[NOIP2013]货车运输

    货车运输

    题目链接

     

    显然,从一点走到另一点的路径中,最小值最大的路径一定在它的最大生成树上

    所以要先求出最大生成树,再在生成树上找最近公共祖先,同时求出最小值。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<vector>
      5 #include<cmath>
      6 using namespace std;
      7 
      8 const int MAXN = 10010 ;
      9 
     10 int n,m,fa[MAXN],f[MAXN][30],deep[MAXN],minn[MAXN][30];
     11 
     12 bool v[MAXN];
     13 
     14 struct Edge{
     15     int x;
     16     int y;
     17     int w;
     18 } e[50010];
     19 
     20 vector<int> son[MAXN],ww[MAXN];
     21 
     22 bool cmp(Edge x,Edge y)
     23 {
     24     return x.w>y.w;
     25 }
     26 
     27 int find(int x)
     28 {
     29     if(fa[x]!=x) fa[x]=find(fa[x]);
     30     return fa[x];
     31 }
     32 
     33 void init()
     34 {
     35     scanf("%d%d",&n,&m);
     36     for(int i=1;i<=n;i++)
     37      fa[i]=i;
     38     for(int i=1;i<=m;i++)
     39      scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].w);
     40 }
     41 
     42 void unionn(int x,int y)
     43 {
     44     fa[find(x)]=find(y);
     45 }
     46 
     47 void mst()
     48 {
     49     sort(e+1,e+1+m,cmp);
     50     int t=0;
     51     for(int i=1;i<=m;i++)
     52     {
     53         int x=e[i].x,y=e[i].y;
     54         if(find(x)!=find(y))
     55         {
     56             unionn(x,y);
     57             t++;
     58             son[x].push_back(y);
     59             ww[x].push_back(e[i].w);
     60              son[y].push_back(x);
     61              ww[y].push_back(e[i].w);
     62              if(t==n-1) break;
     63          }
     64     }
     65 }
     66 
     67 void build(int now,int d)
     68 {
     69     v[now]=1;
     70     deep[now]=d;
     71     for(int i=1;(1<<i)<=deep[now];i++)
     72     {
     73         minn[now][i]=min(minn[now][i-1],minn[f[now][i-1]][i-1]);
     74         f[now][i]=f[f[now][i-1]][i-1];
     75     }
     76     for(int i=0;i<son[now].size();i++)
     77      if(!v[son[now][i]])
     78      {
     79          int u=son[now][i];
     80          minn[u][0]=ww[now][i];
     81          f[u][0]=now;
     82          build(u,d+1);
     83      }
     84 }
     85 
     86 int lca(int x,int y)
     87 {
     88     int ans=0x7fffffff;
     89     if(deep[x]!=deep[y])
     90     {
     91         if(deep[x]>deep[y]) swap(x,y);
     92         for(int i=20;i>=0;i--)
     93          if(deep[f[y][i]]>=deep[x])
     94          {
     95              ans=min(ans,minn[y][i]);
     96              y=f[y][i];
     97          }
     98     }
     99     if(x==y) return ans;
    100     for(int i=20;i>=0;i--)
    101      if(f[x][i]!=f[y][i])
    102      {
    103          ans=min(ans,minn[x][i]);
    104          ans=min(ans,minn[y][i]);
    105          x=f[x][i];
    106          y=f[y][i];
    107      }
    108     ans=min(ans,minn[x][0]);
    109     ans=min(ans,minn[y][0]);
    110     if(ans==0x7fffffff||ans==0)
    111     ans=-1;
    112     return ans;
    113 }
    114 
    115 void work()
    116 {
    117     int q;
    118     scanf("%d",&q);
    119     int x,y;
    120     while(q--)
    121     {
    122         scanf("%d%d",&x,&y);
    123         if(find(x)!=find(y))
    124         printf("-1
    ");
    125         else
    126         printf("%d
    ",lca(x,y));
    127     }
    128 }
    129 
    130 int main()
    131 {
    132     init();
    133     mst();
    134     for(int i=1;i<=n;i++)
    135     {
    136         if(!v[i])
    137         build(i,1);
    138     }
    139      work();
    140     return 0;
    141 }
  • 相关阅读:
    [HEOI2015]兔子与樱花
    [HNOI2015]亚瑟王
    [JSOI2011]分特产
    某考试 T3 sine
    [JSOI2015]最小表示
    51NOD 1258 序列求和 V4
    Codeforces 622F The Sum of the k-th Powers
    Loj #6261. 一个人的高三楼
    [HAOI????] 硬币购物
    bzoj4318 OSU!
  • 原文地址:https://www.cnblogs.com/yjkhhh/p/8521369.html
Copyright © 2011-2022 走看看