求助,80pts
查看原帖
求助,80pts
366516
xuyiyang楼主2023/3/23 21:00

2和9 WA了

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 500005, M = N * 2;

typedef pair<int, int> PII;

int n, m;
int h[N], e[M], ne[M], idx;
int dfn[N], s[N], cycle_cnt, time_stamp, from[N], cnt, id[N], sum[N], peri[N];
int q[N], depth[N], fa[N][20];
int p[N];
bool st[N];

int find(int x)
{
    if (p[x] != x) p[x] = find(p[x]);
    return p[x];
}

void add(int a, int b)
{
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
}

void get_cycle(int x, int y)
{
    cycle_cnt ++ ;
    sum[y] = 1;
    while (y != x)
    {
        s[ ++ cnt] = y;
        id[y] = cycle_cnt;
        
        int next_y = e[from[y] ^ 1];
        sum[next_y] = sum[y] + 1;
        y = next_y;
    }
    s[ ++ cnt] = x;
    peri[cycle_cnt] = sum[x];
    id[x] = cycle_cnt;
    
    for (int i = 1; i <= cnt; i ++ ) st[s[i]] = true;
}

void dfs(int u)
{
    dfn[u] = ++ time_stamp;
    
    for (int i = h[u]; ~i; i = ne[i])
    {
        int j = e[i];
        
        if (!dfn[j])
        {
            from[j] = i;
            dfs(j);
        }
        else if ((i ^ 1) != from[u] && dfn[u] <= dfn[j]) 
            get_cycle(u, j);
    }
}

void bfs(int u)
{
    int hh = 0, tt = 0;
    q[0] = u;
    fa[u][0] = u;
    
    depth[u] = 1;
    
    while (hh <= tt)
    {
        int t = q[hh ++ ];
        
        for (int i = h[t]; ~i; i = ne[i])
        {
            int j = e[i];
            
            if (st[j] || depth[j]) continue;
            
            depth[j] = depth[t] + 1;
            fa[j][0] = t;
            
            for (int k = 1; k <= 19; k ++ ) fa[j][k] = fa[fa[j][k - 1]][k - 1];
            
            q[ ++ tt] = j;
        }
    }
}

PII lca(int a, int b)
{
    bool is_swap = false;
    if (depth[a] < depth[b]) swap(a, b), is_swap = true;
    
    for (int i = 19; i >= 0; i -- )
        if (depth[fa[a][i]] >= depth[b])
            a = fa[a][i];
    
    if (a == b) return (PII){a, b};
    
    for (int i = 19; i >= 0; i -- )
        if (fa[a][i] != fa[b][i])
            a = fa[a][i], b = fa[b][i];
    
    return is_swap ? (PII){fa[b][0], fa[a][0]} : (PII){fa[a][0], fa[b][0]};
}

int main()
{
    memset(h, -1, sizeof h);
    scanf("%d%d", &n, &m);
    
    for (int i = 1; i <= n; i ++ ) p[i] = i;

    for (int i = 1; i <= n; i ++ )
    {
        int a;
        scanf("%d", &a);
        
        add(a, i), add(i, a);
        
        a = find(a);
        int b = find(i);
        if (a != b) p[a] = b; 
    }
    
    memset(from, -1, sizeof from);
    for (int u = 1; u <= n; u ++ )
        if (!dfn[u])
        {
            cnt = 0;
            dfs(u);
            
            // for (int i = 1; i <= cnt; i ++ ) printf("%d ", s[i]);
            // puts("");
            // printf("%d\n", peri[id[s[1]]]);
            
            for (int i = 1; i <= cnt; i ++ ) bfs(s[i]); 
        }
    
    while (m -- )
    {
        int a, b;
        scanf("%d%d", &a, &b);
        
        if (find(a) != find(b)) puts("-1 -1");
        else
        {
            auto [x, y] = lca(a, b);
            
            //printf("%d %d\n", x, y);
            if (x == y) printf("%d %d\n", depth[a] - depth[x], depth[b] - depth[y]);
            else
            {
                int dx = depth[a] - depth[x], dy = depth[b] - depth[y];
                
                int lx = sum[x], ly = sum[y];
                int first = ly > lx ? ly - lx : peri[id[x]] - (lx - ly);
                int second = lx > ly ? lx - ly : peri[id[y]] - (ly - lx);
                
                if (max(dx + first, dy) != max(dx, dy + second))
                {
                    if (max(dx + first, dy) < max(dx, dy + second)) printf("%d %d\n", dx + first, dy);
                    else printf("%d %d\n", dx, dy + second);
                }
                else if (min(dx + first, dy) != min(dx, dy + second))
                {
                    if (min(dx + first, dy) < min(dx, dy + second)) printf("%d %d\n", dx + first, dy);
                    else printf("%d %d\n", dx, dy + second);
                }
                else 
                {
                    if (dx + first >= dy) printf("%d %d\n", dx + first, dy);
                    else printf("%d %d\n", dx, dy + second);
                }
            }
        }
    }
    
    return 0;
}
2023/3/23 21:00
加载中...