60分求助
查看原帖
60分求助
1358004
moonlightandyou楼主2024/5/30 21:08
#include <stdio.h>
#include <stdlib.h>

#define MAX 100010

typedef long long ll;

typedef struct edge
{
    int v;   // 该边的目标节点编号
    struct edge* next;  // 指向下一条边的指针
}edge;

struct edge* e[MAX];   
ll fa[MAX];    //存储每个节点的父节点
ll dep[MAX];   //存储每个节点的深度
ll son[MAX];   //存储每个节点的重儿子
ll siz[MAX];   //存储以每个节点为根的子树的大小
ll top[MAX];   //存储每个节点所在的重链的顶部节点
ll sum[MAX];   //存储从根节点到每个节点的权值和
ll w[MAX];     //存储每个节点的权值
int n, m;

void add_edge(int u, int v)
{
	struct edge* p = (struct edge*)malloc(sizeof(struct edge));
	p->v = v;
	p->next = e[u];
	e[u] = p;
}

// 根据每个节点的出度更新所有节点的权值
void update_weights() 
{
    for (int i = 1; i <= n; i++) 
    {
        w[i] = 0;
    }

    for (int u = 1; u <= n; u++) 
    {
        for (struct edge* p = e[u]; p != NULL; p = p->next) 
        {
            w[u]++;
        }
    }
}


void dfs1(ll u, ll f) 
{
    fa[u] = f;
    dep[u] = dep[f] + 1;
    siz[u] = 1;
    sum[u] = sum[f] + w[u]; 

    for (struct edge* p = e[u]; p != NULL; p = p->next) 
    {
        ll v = p->v;
        if (v == f) continue; 
        dfs1(v, u);
        siz[u] += siz[v];
        if (siz[v] > siz[son[u]]) 
        {
            son[u] = v; 
        }
    }
}


void dfs2(ll u, ll t)
{
	top[u] = t;
	if (son[u] == 0) return;
	dfs2(son[u], t);
	for (struct edge* p = e[u]; p != NULL; p = p->next)
	{
		ll v = p->v;
		if (v == fa[u] || v == son[u]) continue;
		dfs2(v, v);
	}

}

ll lca(ll x, ll y)
{
    while (top[x] != top[y])
    {
        if (dep[top[x]] > dep[top[y]]) x = fa[top[x]];
        else y = fa[top[y]];
    }
    return dep[x] < dep[y] ? x : y;
}

ll get(ll x, ll y)
{
    if (x == 0 || y == 0) return 0;
    return sum[x] + sum[y] - 2*sum[lca(x, y)]+w[lca(x,y)];
}

int main(void)
{
	scanf("%d%d", &n, &m);
	for (int i = 1; i < n; i++)
	{
        int u, v;
		scanf("%d%d", &u, &v);
		add_edge(u, v);
		add_edge(v, u);
	}

	update_weights();

	dfs1(1, 0);
	dfs2(1, 1);

	for (int i = 1; i <= m; i++)
	{
		int a, b;
		scanf("%d%d", &a, &b);
		if (a == b) printf("1\n");
		else
		printf("%lld\n", get(a, b));
	}

	return 0;

}

2024/5/30 21:08
加载中...