zoukankan      html  css  js  c++  java
  • 【tarjan+lca】有机化学之神偶尔会做作弊

     P2783 有机化学之神偶尔会做作弊

    我觉得我对的一比可就是wa三个点我决定不改了毕竟我已经领会到精髓了

    (还有这种人?????

    就是tarjan缩点+倍增求lca

    因为是无向图, 要判断一下, dfs的时候不能返回上一个点, 否则全图就是一整个强连通分量了qwq

      1 #include<cmath>
      2 #include<cstdio>
      3 #include<iostream>
      4 using namespace std;
      5 const int maxn = 10010, maxm = 50050;
      6 int n, m, q, log2n, num = 0, cot = 0, top = 0, tim = 0;
      7 int head[maxm], hear[maxm], dep[maxn], sd[maxn], jump[maxn][23], sta[maxn], low[maxn], dfn[maxn], x[maxm], y[maxm];
      8 bool vis[maxn];
      9 struct edg {
     10     int nxt, to;
     11 }e[maxm << 1], edge[maxm << 1];
     12 void add(int from, int to) {
     13     e[++num].to = to;
     14     e[num].nxt = head[from];
     15     head[from] = num;
     16 }
     17 void readd(int from, int to) {
     18     edge[++cot].to = to;
     19     edge[cot].nxt = hear[from];
     20     hear[from] = cot;
     21 }
     22 void tarjan(int u, int fa) {
     23     low[u] = dfn[u] = ++tim;
     24     sta[++top] = u;
     25     vis[u] = 1;
     26     for(int i = head[u]; i; i = e[i].nxt) {
     27         int v = e[i].to;
     28         if(v != fa) {
     29             if(!dfn[v]) 
     30             {
     31                 tarjan(v, u);
     32                 low[u] = min(low[u], low[v]);
     33             }
     34             else if(vis[v]) low[u] = min(low[u], dfn[v]);
     35         }
     36     }
     37     if(dfn[u] == low[u]) {
     38         int y;
     39         while(y = sta[top--]) {
     40             sd[y] = u;
     41             vis[y] = 0;
     42             if(y == u) break;
     43         }
     44     }
     45 }
     46 void dfs(int x) {
     47     for(int i = hear[x]; i; i = edge[i].nxt) 
     48     {
     49         int y = edge[i].to;
     50         if(y != jump[x][0]) 
     51         {
     52             dep[y] = dep[x] + 1;
     53             jump[y][0] = x;
     54             dfs(y);
     55         }
     56     }
     57 }
     58 void init() {
     59     for(int i = 1; i <= log2n; i++)
     60         for(int j = 1; j <= n; j++)
     61             jump[j][i] = jump[jump[j][i-1]][i-1];
     62 }
     63 int LCA(int x, int y) {
     64     if(dep[x] < dep[y]) swap(x, y);
     65     int t = dep[x] - dep[y];
     66     for(int i = 0; (1<<i) <= n; i++) 
     67         if(t & (1<<i)) x = jump[x][i];
     68     if(x == y) return x;
     69     for(int i = log2n; i >= 0; i--)    {
     70         if(jump[x][i] != jump[y][i]) {
     71             x = jump[x][i];
     72             y = jump[y][i];
     73         }
     74     }
     75     return jump[x][0];
     76 }
     77 void print(int ans) {
     78     if (!ans) return;
     79     print(ans >> 1);
     80     printf("%d", ans & 1);
     81 }
     82 int main() {
     83     scanf("%d%d", &n, &m);
     84     log2n = log(n) / log(2) + 1;
     85     for(int i = 1; i <= m; i++) {
     86         int u, v;
     87         scanf("%d%d", &x[i], &y[i]);
     88         add(x[i], y[i]), add(y[i], x[i]);
     89     }
     90     for(int i = 1; i <= n; i++)
     91         if(!dfn[i]) tarjan(i, i);
     92     for(int i = 1; i <= m; i++) {
     93         if(sd[x[i]] != sd[y[i]]){
     94             readd(sd[x[i]], sd[y[i]]), readd(sd[y[i]], sd[x[i]]);
     95         }
     96     }
     97     jump[1][0] = 0;
     98     dep[1] = 1;
     99     dfs(1);
    100     init();
    101     scanf("%d", &q);
    102     for(int i = 1; i <= q; i++) {
    103         int u, v;
    104         scanf("%d%d", &u, &v);
    105         int lca = LCA(u, v);
    106         int ans = dep[u] + dep[v] - 2*dep[lca] + 1;
    107         print(ans);
    108         printf("
    ");
    109     }
    110     return 0;
    111 }
  • 相关阅读:
    【面积并】 Atlantis
    【动态前k大 贪心】 Gone Fishing
    【复杂枚举】 library
    【双端队列bfs 网格图建图】拯救大兵瑞恩
    【奇偶传递关系 边带权】 奇偶游戏
    【权值并查集】 supermarket
    CF w4d3 A. Pythagorean Theorem II
    CF w4d2 C. Purification
    CF w4d2 B. Road Construction
    CF w4d2 A. Cakeminator
  • 原文地址:https://www.cnblogs.com/Hwjia/p/9864662.html
Copyright © 2011-2022 走看看