2 solutions

  • 1
    @ 2025-12-22 13:20:47
    1. 图论:

      删除环上点 SS 及相关边后,剩余图为森林。其连通块个数满足公式:

      • 连通块个数=剩余点数剩余边数\text{连通块个数} = \text{剩余点数} - \text{剩余边数}
    2. 公式应用

      SS:环上的点集

      S|S|:环上点的个数

      AA:环上边的个数,满足 S=A+1|S| = A + 1

      EdelE_{\text{del}}:删除的边数

      结合森林公式推导:

      • 剩余点数 = nSn - |S|

      • 剩余边数 = 总边数 Edel=(n1)Edel- E_{\text{del}} = (n-1) - E_{\text{del}}

      • 连通块个数 = $(n - |S|) - [(n-1) - E_{\text{del}}] = E_{\text{del}} - |S| + 1$

      进一步推导 EdelE_{\text{del}}

      sum_degS\text{sum\_deg}_SSS 中所有点的度数和。

      环上内部边数为 AA,每条内部边被 SS 中两点各计数一次,外部边(一端在 SS)仅计数一次。因此:

      • $\text{sum\_deg}_S = 2 \times \text{内部边数} + \text{外部边数} = 2A + (E_{\text{del}} - A) = A + E_{\text{del}}$

      • Edel=sum_degSAE_{\text{del}} = \text{sum\_deg}_S - A

      代入连通块个数公式:

      • $⇒\text{ans} = (\text{sum\_deg}_S - A) - (A + 1) + 1 = \text{sum\_deg}_S - 2A$
    #include<bits/stdc++.h>
    using namespace std;
    #define FAST_IO ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
    #define int long long
    #define MAXN 1000005
    #define LOG 25
    int n,q;
    vector<int> g[MAXN];
    int dep[MAXN],st[MAXN][LOG];
    int deg[MAXN],sum[MAXN];
    int lg[MAXN];
    void dfs(int u,int pre)
    {
    	dep[u]=dep[pre]+1;
    	st[u][0]=pre;
    	sum[u]=sum[pre]+deg[u];
    	for(int i=1;i<=lg[dep[u]];i++) st[u][i]=st[st[u][i-1]][i-1];
    	for(int v:g[u]) if(v!=pre) dfs(v,u);
    }
    int get_lca(int u,int v)
    {
    	if(dep[u]<dep[v]) swap(u,v);
    	for(int i=lg[dep[u]];i>=0;i--)
    	{
    		if(dep[u]-(1<<i)>=dep[v]) u=st[u][i];
    	}
    	if(u==v) return u;
    	for(int i=lg[dep[u]];i>=0;i--)
    	{
    		if(st[u][i]!=st[v][i]) u=st[u][i],v=st[v][i];
    	}
    	return st[u][0];
    }
    signed main()
    {
    	FAST_IO;
    	//freopen("easy.in","r",stdin);
    	//freopen("easy.out","w",stdout);
    	cin>>n>>q;
    	lg[1]=0;for(int i=2;i<=n;i++) lg[i]=lg[i>>1]+1;
    	for(int i=1;i<=n-1;i++)
    	{
    		int x,y;
    		cin>>x>>y;
    		g[x].push_back(y),g[y].push_back(x);
    		deg[x]++,deg[y]++;
    	}
    	dfs(1,0);
    	while(q--)
    	{
    		int u,v;
    		cin>>u>>v;
    		int lca=get_lca(u,v);
    		int deg_sum=sum[u]+sum[v]-2*sum[lca]+deg[lca];
    		int cnt=dep[u]+dep[v]-2*dep[lca];
    		int ans=deg_sum-2*cnt;
    		cout<<ans<<'\n';
    	}
    	return 0;
    }
    

    Information

    ID
    714
    Time
    4000ms
    Memory
    1024MiB
    Difficulty
    10
    Tags
    # Submissions
    8
    Accepted
    2
    Uploaded By