zoukankan      html  css  js  c++  java
  • uva 11354 Bond

    题意:

    邦德在逃命!他在一个有N个城市,由M条边连接的道路网中。一条路的危险度被定义为这条路上危险度最大的边的危险度。

    现在给出若干个询问,s,t,问从s到t的最小的危险度是多少。

    思路:

    首先可以证明这条路是固定的,就是最小生成树,证明略。

    之后就是计算生成树上两点间的最长边,用prim算法预处理的话,由于N的规模较大,所以会超时。

    由于MST是一棵树,想到树上两点之间的距离有O(log(n))的求法,即倍增求lca,按照同样的处理方法,只不过维护最大值,就可以在O(log(n))的时间内求出两点之间的最长边,查询为Q,总复杂度Qlog(n)。

    代码:

      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <algorithm>
      4 #include <vector>
      5 #include <math.h>
      6 using namespace std;
      7 
      8 const int maxn = 50005;
      9 //const int inf = 0x3f3f3f3f;
     10 
     11 struct edge
     12 {
     13     int fr,to,len;
     14     
     15     edge(int a,int b,int c)
     16     {
     17         fr = a;
     18         to = b;
     19         len = c;
     20     }
     21 };
     22 
     23 bool cmp(edge x,edge y)
     24 {
     25     return x.len < y.len;
     26 }
     27 
     28 vector<edge> g[maxn],es;
     29 int p[maxn][35];
     30 int fa[maxn];
     31 int par[maxn];
     32 bool vis[maxn];
     33 int md[maxn][35];
     34 int deep[maxn];
     35 
     36 int fin(int x)
     37 {
     38     if (x == par[x]) return x;
     39     else return par[x] = fin(par[x]);
     40 }
     41 
     42 void unit(int x,int y)
     43 {
     44     x = fin(x);
     45     y = fin(y);
     46     
     47     if (x == y) return;
     48     
     49     par[x] = y;
     50 }
     51 
     52 void dfs(int u)
     53 {
     54     vis[u] = 1;
     55     
     56     for (int i = 0;i < g[u].size();i++)
     57     {
     58         edge e = g[u][i];
     59         
     60         int to = e.to;
     61         
     62         if (vis[to]) continue;
     63         
     64         fa[to] = u;
     65         
     66         deep[to] = deep[u] + 1;
     67         
     68         md[to][0] = e.len;
     69         
     70         dfs(to);
     71     }
     72 }
     73 
     74 void pre_deal(int n)
     75 {
     76     for (int i = 0;i <= n;i++)
     77     {
     78         p[i][0] = fa[i];
     79     }
     80     
     81     //int sz = (int)(log(n*1.0) / log(2.0)) + 1;
     82     
     83     for (int j = 1;j<= 20;j++)
     84     {
     85         for (int i = 1;i <= n;i++)
     86         {
     87             p[i][j] = p[p[i][j-1]][j-1];
     88             md[i][j] = max(md[i][j-1],md[p[i][j-1]][j-1]);
     89         }
     90     }
     91 }
     92 
     93 int query(int a,int b,int n)
     94 {
     95     if (deep[a] < deep[b]) swap(a,b);
     96     
     97     int c = deep[a] - deep[b];
     98     
     99     int ans = 0;
    100     
    101     //int sz = (int)(log(n * 1.0) / log(2.0)) + 1;
    102     
    103     for (int i = 0;i <= 20;i++)
    104     {
    105         if (c & (1 << i))
    106         {
    107             ans = max(ans,md[a][i]);
    108             a = p[a][i];
    109             //printf("%d **
    ",ans);
    110         } 
    111     }
    112     
    113     if (a == b) return ans;
    114     else
    115     {
    116         for (int i = 20;i >= 0;i--)
    117         {
    118             if (p[a][i] != p[b][i])
    119             {
    120                 ans = max(ans,md[a][i]);
    121                 ans = max(ans,md[b][i]);
    122                 
    123                 a = p[a][i];
    124                 b = p[b][i];
    125             }
    126         }
    127     }
    128     
    129     ans = max(ans,md[a][0]);
    130     ans = max(ans,md[b][0]);
    131     
    132     return ans;
    133 }
    134 
    135 void init(int n)
    136 {
    137     for (int i = 0;i <= n;i++)
    138     {
    139         g[i].clear();
    140         par[i] = i;
    141     }
    142     
    143     es.clear();
    144     
    145     memset(vis,0,sizeof(vis));
    146     memset(md,0,sizeof(md));
    147     memset(deep,0,sizeof(deep));
    148     memset(md,0,sizeof(md));
    149 }
    150 
    151 int main()
    152 {
    153     int n,m;
    154     
    155     int kase = 0;
    156     
    157     while (scanf("%d%d",&n,&m) != EOF)
    158     {
    159         if (kase++) printf("
    ");
    160         
    161         init(n);
    162         
    163         for (int i = 0;i < m;i++)
    164         {
    165             int a,b,c;
    166             
    167             scanf("%d%d%d",&a,&b,&c);
    168             
    169             es.push_back(edge(a,b,c));
    170         }
    171         
    172         sort(es.begin(),es.end(),cmp);
    173         
    174         for (int i = 0;i < m;i++)
    175         {
    176             int x = es[i].fr,y = es[i].to;
    177             
    178             if (fin(x) == fin(y)) continue;
    179             
    180             unit(x,y);
    181             
    182             g[x].push_back(edge(x,y,es[i].len));
    183             g[y].push_back(edge(y,x,es[i].len));
    184         }
    185         
    186         deep[1] = 0;
    187         //
    188         dfs(1);
    189         //printf("233
    ");
    190         pre_deal(n);
    191         
    192         int q;
    193         
    194         scanf("%d",&q);
    195         
    196         for (int i = 0;i < q;i++)
    197         {
    198             int a,b;
    199             
    200             int ans = 0;
    201             
    202             scanf("%d%d",&a,&b);
    203             
    204             ans = query(a,b,n);
    205             
    206             printf("%d
    ",ans);
    207         }
    208     }
    209     
    210     return 0;
    211 }
  • 相关阅读:
    程序经理_产品经理_项目经理
    github上排名靠前的java项目之_storm
    垂直型与水平型电子商务网站的理解
    关于驱动更新的一点学习
    Balanced Binary Tree
    Gray Code
    Best Time to Buy and Sell Stock II
    Best Time to Buy and Sell Stock
    Maximum Depth of Binary Tree
    Next Permutation
  • 原文地址:https://www.cnblogs.com/kickit/p/8809019.html
Copyright © 2011-2022 走看看