zoukankan      html  css  js  c++  java
  • uva11354 LCA+最小生成树+dp

    源自大白书

    题意 有n座城市通过m条双向道路相连,每条道路都有一个危险系数。你的任务是回答若干个询问,每个询问包含一个起点s和一个终点t,要求找到一条从s到t的路,使得途径所有的边的大最大危险系数最小。

    解: 首先求出最小生成树,并把它改写成有根树,让fa[i]和cost[i]分别表示节点i的父亲编号和它与父亲之间的边权,L[i]表示节点i的深度,接下来通过预处理计算出数组anc 和 maxcost 其中anc[i][j] 表示节点i的2^j 级祖先的编号 macost[i][j] 表示i到2^j级 祖先之间的最大权值。

    有了预处理 私用LCA 来查询结果, 查询p,q, 并且p比q深, 则可以先把p提升到和q处于同一级的位置,然后用二进制展开的方法不断把p和q同时往上提(保证二者深度相等),同时更新最大的边权

      1 #include <iostream>
      2 #include <algorithm>
      3 #include <cstdio>
      4 #include <string.h>
      5 #include <vector>
      6 using namespace std;
      7 const int maxn = 50000+10;
      8 const int INF =2000000000;
      9 struct Edge{
     10    int from,to, dist;
     11    bool operator <(const Edge & rhs)const{
     12        return dist<rhs.dist;
     13    }
     14 }E[maxn*2];
     15 struct ed{
     16   int to,dist;
     17 };
     18 vector<ed> G[maxn];
     19 int fa[maxn],per[maxn],cost[maxn],L[maxn];
     20 int anc[maxn][20],maxcost[maxn][20];
     21 void inti(int n){
     22     for(int i =0; i<n; i++){
     23          per[i] = i;
     24          G[i].clear();
     25     }
     26 }
     27 void preprocess( int n){
     28     for(int i=0; i<n ; i++){
     29            anc[i][0] = fa[i]; maxcost[i][0]=cost[i];
     30            for(int j=1; (1<<j)<n; j++) anc[i][j]=-1;
     31     }
     32     for(int j =1; (1<<j)<n; j++)
     33         for(int i=0; i<n; i++){
     34         if(anc[i][j-1]!=-1){
     35               int a = anc[i][j-1];
     36               anc[i][j]=anc[a][j-1];
     37               maxcost[i][j] = max(maxcost[i][j-1],maxcost[a][j-1]);
     38         }
     39     }
     40 }
     41 int fid(int u){
     42    return per[u]==u?u:(per[u]= fid(per[u]));
     43 }
     44 void dfs(int u, int p,int dist, int depth){
     45      fa[u]=p; cost[u] = dist; L[u] = depth;
     46      for(int i = 0; i<(int)G[u].size(); ++i){
     47           ed e = G[u][i];
     48           if(e.to == p) continue;
     49           dfs(e.to,u,e.dist,depth+1);
     50      }
     51 }
     52 int query(int p, int q){
     53     int log;
     54     if(L[p]<L[q]) swap(p,q);
     55     for( log =1; (1<<log)<=L[p]; log++); log--;
     56     int ans=-INF;
     57     for(int i = log ; i>=0; i--)
     58     if( L[p] - (1<<i) >= L[q] ){
     59         ans = max(ans,maxcost[p][i]);
     60         p = anc[p][i];
     61     }
     62     if(p==q) return ans;
     63     for(int i=log; i>=0; i--)
     64     if(anc[p][i]!=-1 && anc[p][i]!=anc[q][i]){
     65          ans = max(ans,maxcost[p][i]); p = anc[p][i];
     66          ans = max(ans,maxcost[q][i]); q = anc[q][i];
     67     }
     68     ans = max(ans,cost[p]);
     69     ans = max(ans,cost[q]);
     70     return ans;
     71 }
     72 int main()
     73 {
     74     int n,m,f=0;
     75     while(scanf("%d%d",&n,&m)==2){
     76          inti(n);
     77          for(int i=0; i<m ; i++){
     78              int x,y,d;
     79              scanf("%d%d%d",&x,&y,&d);
     80              x--,y--;
     81              E[i]=(Edge){x,y,d};
     82          }
     83          int lest = n;
     84          sort(E,E+m);
     85          for(int i=0; i<m; i++){
     86              int a = E[i].from,b=E[i].to, dist= E[i].dist;
     87              int ca = fid(a),cb = fid(b);
     88              if(ca!=cb){
     89                   per[ca] =cb;
     90                   lest--;
     91                   G[a].push_back((ed){b,dist} );
     92                   G[b].push_back((ed){a,dist} );
     93                   if(lest==1) break;
     94              }
     95          }
     96          dfs(0,-1,0,0);
     97          preprocess(n);
     98           int Q;
     99          if(f)
    100             puts("");
    101          else f=1;
    102           scanf("%d",&Q);
    103           for(int i =0; i<Q; i++){
    104                int s,t;
    105                scanf("%d%d",&s,&t);
    106                s--;t--;
    107               printf("%d
    ",query(s,t));
    108           }
    109 
    110     }
    111 
    112     return 0;
    113 }
  • 相关阅读:
    Pentaho Data Integration (二) Spoon
    Pentaho Data Integration笔记 (一):安装
    透视纹理引发的对于插值的思考
    读取位图(bitmap)实现及其要点
    关于渲染流水线的几何变化
    关于C++中不同类之间的赋值问题——存疑
    uva 12284 直接判断
    uva 12549 最大流
    uva 12544 无向图最小环
    uva 12587 二分枚举
  • 原文地址:https://www.cnblogs.com/Opaser/p/4366807.html
Copyright © 2011-2022 走看看