zoukankan      html  css  js  c++  java
  • HDU 2874 Connections between cities (LCA)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2874

    题意是给你n个点,m条边(无向),q个询问。接下来m行,每行两个点一个边权,而且这个图不能有环路。然后接下来q行,每行给你两个点,问你这两个点的最短距离是多少,要是不相连,则输出一串英文。

    首先想到的是用(二分)倍增LCA,但是这题的坑点是两个点可能不在同一个图中,所以我dfs的时候用block[i]标记这个点属于哪一个图中,要是这个点在同一个图中,答案就是cost[u] + cost[v] - 2*cost[lca(u , v)]。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <vector>
     5 using namespace std;
     6 const int MAXN = 10005;
     7 struct data {
     8     int next , to , w;
     9 }edge[MAXN * 4];
    10 int head[MAXN] , par[MAXN * 3][15] , dep[MAXN] , cont , cost[MAXN] , block[MAXN];
    11 
    12 void init() {
    13     cont = 0;
    14     //memset(par , -1 , sizeof(par));
    15     memset(head , -1 , sizeof(head));
    16     memset(block , 0 , sizeof(block));
    17 }
    18 
    19 inline void add(int u , int v , int w) {
    20     edge[cont].next = head[u];
    21     edge[cont].to = v;
    22     edge[cont].w = w;
    23     head[u] = cont++;
    24 }
    25 
    26 void dfs(int u , int p , int d , int node , int w) {
    27     dep[u] = d;
    28     par[u][0] = p;
    29     block[u] = node;
    30     cost[u] = w;
    31     int v;
    32     for(int i = head[u] ; ~i ; i = edge[i].next) {
    33         v = edge[i].to;
    34         if(v == p)
    35             continue;
    36         dfs(v , u , d + 1 , node , w + edge[i].w);
    37     }
    38 }
    39 
    40 int lca(int u , int v) {
    41     if(dep[u] < dep[v])
    42         swap(u , v);
    43     for(int k = 0 ; k < 15 ; k++) {
    44         if((dep[u] - dep[v]) >> k & 1) {
    45             u = par[u][k];
    46         }
    47     }
    48     if(u == v)
    49         return v;
    50     for(int k = 14 ; k >= 0 ; k--) {
    51         if(par[u][k] != par[v][k]) {
    52             u = par[u][k];
    53             v = par[v][k];
    54         }
    55     }
    56     return par[u][0];
    57 }
    58 
    59 int main()
    60 {
    61     int n , m , q , u , v , w;
    62     while(~scanf("%d %d %d" , &n , &m , &q)) {
    63         init();
    64         for(int i = 0 ; i < m ; i++) {
    65             scanf("%d %d %d" , &u , &v , &w);
    66             add(u , v , w);
    67             add(v , u , w);
    68         }
    69         int f = 0;
    70         for(int i = 1 ; i <= n ; i++) {
    71             if(!block[i]) {
    72                 dfs(i , -1 , 0 , ++f , 0);
    73             }
    74         }
    75         for(int k = 0 ; k < 14 ; k++) {
    76             for(int i = 1 ; i <= n ; i++) {
    77                 if(par[i][k] <= 0)
    78                     par[i][k + 1] = par[i][k];
    79                 else
    80                     par[i][k + 1] = par[par[i][k]][k];
    81             }
    82         }
    83         while(q--) {
    84             scanf("%d %d" , &u , &v);
    85             if(block[u] != block[v]) {
    86                 printf("Not connected
    ");
    87             }
    88             else {
    89                 printf("%d
    " , cost[u] + cost[v] - 2 * cost[lca(u , v)]);
    90             }
    91         }
    92     }
    93 }
  • 相关阅读:
    【SQL】DBCC(zz)
    Temporary Tables and Table Variables
    SQL特殊字符处理zz
    更改 Office 解决方案的安装路径
    SQL优化
    zzSQL Server性能优化
    SQL Server2005 表分区三步曲(zz)
    zz精妙SQL
    Deal with an annoying Message in Excel
    SQL技巧总结
  • 原文地址:https://www.cnblogs.com/Recoder/p/5268707.html
Copyright © 2011-2022 走看看