zoukankan      html  css  js  c++  java
  • wikioi1036 商务旅行 挺水的lca

    链接:http://wikioi.com/problem/1036/

    题意不写了。

    思路:很明显找到lca然后用两个点的深度相加-lca的深度就是这一步的最近步数。

      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <iostream>
      4 #include <algorithm>
      5 #include <stdlib.h>
      6 #include <vector>
      7 #include <queue>
      8 #define loop(s,i,n) for(i = s;i < n;i++)
      9 #define cl(a,b) memset(a,b,sizeof(a))
     10 using namespace std;
     11 const int maxn = 100005;
     12 int low[maxn],dfn[maxn],set[maxn],father[maxn],dfsclock,cut;
     13 int depth[maxn];
     14 
     15 vector<int >g[maxn];
     16 int find(int x)
     17 {
     18     if(set[x] != x)
     19     set[x] = find(set[x]);
     20 
     21     return set[x];
     22 }
     23 int merge(int x,int y)
     24 {
     25     x = find(x);
     26     y = find(y);
     27     if(y != x)
     28     {
     29         set[y] = x;
     30         return 1;
     31     }
     32     return 0;
     33 }
     34 void tarjan(int u,int pre,int deep)
     35 {
     36     int v,i,j;
     37     dfn[u] = low[u] = ++dfsclock;
     38     depth[u] = deep;
     39     loop(0,i,g[u].size())
     40     {
     41         v = g[u][i];
     42         if(!dfn[v])
     43         {
     44             tarjan(v,u,deep+1);
     45             father[v] = u;
     46             low[u] = min(low[v],low[u]);
     47             if(low[v] > dfn[u])
     48             cut++;
     49             else
     50             merge(u,v);
     51         }
     52         else if(v != pre)
     53         low[u] = min(low[u],dfn[v]);
     54     }
     55 }
     56 int lca(int u,int v)
     57 {
     58 
     59     while(u != v)
     60     {
     61         while(dfn[u] >= dfn[v] && u != v)
     62         {
     63             if(merge(u,father[u]))
     64             cut--;
     65             u = father[u];
     66         }
     67         while(dfn[v] >= dfn[u] && u != v)
     68         {
     69             if(merge(v,father[v]))
     70             cut--;
     71             v =  father[v];
     72         }
     73     }
     74     return u;
     75 }
     76 int main()
     77 {
     78     int n,m;
     79     int i,x,y;
     80     scanf("%d",&n);
     81     {
     82         int u,v;
     83         loop(0,i,n+1)
     84         {
     85             g[i].clear();
     86             set[i] = i;
     87             father[i] = 0;
     88         }
     89         loop(1,i,n)
     90         {
     91             scanf("%d %d",&u,&v);
     92             g[u].push_back(v);
     93             g[v].push_back(u);
     94 
     95         }
     96         cl(dfn,0);
     97         cl(low,0);
     98         cut = dfsclock = 0;
     99 
    100         int k;
    101         scanf("%d",&k);
    102         tarjan(1,-1,0);
    103         u = 1;
    104         int ans;
    105         ans = 0;
    106         while(k--)
    107         {
    108             scanf("%d",&v);
    109             int f;
    110             f = lca(u,v);
    111             ans += depth[u]+depth[v]-2*depth[f];
    112             u = v;
    113         }
    114         cout<<ans<<endl;
    115     }
    116     return 0;
    117 }
    View Code
  • 相关阅读:
    concurrent.futures
    HTTP协议
    Web框架原理
    Docker从入门到实战应用
    Mac Homebrew超坑爹的地方
    第6章-7.找出总分最高的学生 (15分)
    第6章-6.求指定层的元素个数 (40分)
    第6章-5.列表元素个数的加权和(1) (40分)
    第6章-4.列表数字元素加权和(1) (40分)
    第6章-3.列表或元组的数字元素求和 (20分)
  • 原文地址:https://www.cnblogs.com/0803yijia/p/3349857.html
Copyright © 2011-2022 走看看