zoukankan      html  css  js  c++  java
  • Egyptian Collegiate Programming Contest (ECPC 2015) C题 Connecting Graph

      这题上次用的是线性求LCA过的,数据比较水,当时没有被T掉(不过线性的做法是在线的)。现在重新的分析一下这个问题。在所有的操作都进行完毕以后,这个图形肯定会变成一棵树,而我们的要求是在这棵树上的一条链上求出边权值t的最大值,那么很显然的可以使用树链剖分来解决这个问题(在做这题之前我还不知道LCA也可以获得一条链上的最值)。然后再看这个问题,因为不论是LCA还是树链剖分,都不能够动态的修改树的形状然后维护最值,因此,这样的做法只能够采用离线的做法。最后需要注意的一点是,因为最后求得的这棵树,在时间i的时候已经把后面的操作也加上了,也就是说如果这条链上的最值大于时间i,那么在这个时刻i实际上这两点是没有被联通的。

      代码如下(LCA):

      1 #include <stdio.h>
      2 #include <algorithm>
      3 #include <string.h>
      4 #include <vector>
      5 using namespace std;
      6 const int N = 1e5 + 10;
      7 const int log_N = 20 + 1;
      8 typedef pair<int,int> pii;
      9 
     10 int root[N];
     11 int find(int x) {return x == root[x] ? x : root[x] = find(root[x]);}
     12 
     13 int n,m,T;
     14 int par[log_N][N];
     15 int dep[N];
     16 int op[N],uu[N],vv[N];
     17 vector<pii> G[N];
     18 int mx[log_N][N];
     19 void dfs(int u,int fa,int d)
     20 {
     21     par[0][u] = fa;
     22     dep[u] = d;
     23     for(int i=0;i<G[u].size();i++)
     24     {
     25         pii e = G[u][i];
     26         int v = e.first, w = e.second;
     27         if(v != fa)
     28         {
     29             mx[0][v] = w;
     30             dfs(v, u, d + 1);
     31         }
     32     }
     33 }
     34 void init_lca()
     35 {
     36     memset(par[0], -1, sizeof(par[0]));
     37     memset(mx,0,sizeof(mx));
     38     for(int i=1;i<=n;i++) if(par[0][i] == -1) dfs(i, -1, 0);
     39     for(int k=0;k+1<log_N;k++)
     40     {
     41         for(int u=1;u<=n;u++)
     42         {
     43             if(par[k][u] < 0) par[k+1][u] = -1;
     44             else par[k + 1][u] = par[k][par[k][u]], mx[k + 1][u] = max(mx[k][u], mx[k][par[k][u]]);
     45         }
     46     }
     47 }
     48 
     49 void solve_lca(int u,int v,int i)
     50 {
     51     if(find(u) != find(v)) puts("-1");
     52     else
     53     {
     54         int ans = -1;
     55         if(dep[u] > dep[v]) swap(u, v);
     56         for(int k=0;k<log_N;k++)
     57         {
     58             if((dep[v] - dep[u]) >> k & 1)
     59             {
     60                 ans = max(ans, mx[k][v]);
     61                 v = par[k][v];
     62             }
     63         }
     64         if(u == v) printf("%d
    ",ans > i ? -1 : ans);
     65         else
     66         {
     67             for(int k = log_N - 1; k >= 0; k--)
     68             {
     69                 if(par[k][u] != par[k][v])
     70                 {
     71                     ans = max(ans, mx[k][u]);
     72                     ans = max(ans, mx[k][v]);
     73                     u = par[k][u];
     74                     v = par[k][v];
     75                 }
     76             }
     77             ans = max(ans, max(mx[0][u], mx[0][v]));
     78             printf("%d
    ",ans > i ? -1 : ans);
     79         }
     80     }
     81 }
     82 
     83 void solve()
     84 {
     85     init_lca();
     86     for(int i=1;i<=m;i++)
     87     {
     88         if(op[i] == 2)
     89         {
     90             solve_lca(uu[i], vv[i], i);
     91         }
     92     }
     93 }
     94 
     95 int main()
     96 {
     97     scanf("%d",&T);
     98     while(T--)
     99     {
    100         scanf("%d%d",&n,&m);
    101         for(int i=1;i<=n;i++) G[i].clear(), root[i] = i;
    102         for(int i=1;i<=m;i++)
    103         {
    104             scanf("%d%d%d",op+i,uu+i,vv+i);
    105             if(op[i] == 1)
    106             {
    107                 int rx = find(uu[i]), ry = find(vv[i]);
    108                 if(rx == ry) continue;
    109                 root[ry] = rx;
    110                 G[uu[i]].push_back(pii(vv[i], i));
    111                 G[vv[i]].push_back(pii(uu[i], i));
    112             }
    113         }
    114         solve();
    115     }
    116     return 0;
    117 }
  • 相关阅读:
    批量编译当前目录下4gl文件
    oracle数据库查看表
    Oracle中授权(grant)和同义词(synonym)
    Oracle中的instr()函数 详解及应用
    T100的程序错误提示方法
    六种 主流ETL 工具的比较
    oracle恢复数据到某个时间点
    Oracle统计一个小时内,一天内、一个星期内、一个月内、一年内的数据
    Linux top命令的用法详细详解
    Win10操作系统无法访问局域网共享文件夹的问题
  • 原文地址:https://www.cnblogs.com/zzyDS/p/6717861.html
Copyright © 2011-2022 走看看