题意

给一个连通图,每次询问两点间最短路。

分析

首先我们取联通的条边,利用,处理出询问的答案。

然后我们最多还剩下条边,我们对这些边的点跑,处理出所有点到该点的距离,
然后遍历所有的询问,更新答案。

时间有点紧

#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define pii pair<int,int>
const int inf = 0x3f3f3f3f;
const int maxn = 201110;
const int M = 1e9+7;
int n,m,q,t=20;

int read()
{
    int x=0,f=1;
    char c=getchar();
    while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
    while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+c-'0',c=getchar();
    return f*x;
}

void print(int x)
{
    if(x < 0) {putchar('-');x = -x;}
    if(x/10) print(x/10);
    putchar(x%10+'0');
}

int head[maxn],to[maxn],Next[maxn],cnt = 2;

void add(int u,int v)
{
    to[cnt] = v;Next[cnt] = head[u];head[u] = cnt;cnt++;
}

int d[maxn],fa[maxn][25];

void dfs(int u,int pre)
{   
    d[u] = d[pre]+1;
    fa[u][0] = pre;
    for(int i = 1; (1<<i) <= d[u]; i++)
    {
        fa[u][i] = fa[fa[u][i-1]][i-1];
    }
    for(int i = head[u]; i ; i = Next[i])
    {
        int v = to[i];
        if(v == pre) continue;
        dfs(v,u);
    }
}

int lca(int x,int y)
{
    if(d[x] > d[y]) swap(x,y);
    for(int i = t; i >= 0; i--)
    {
        if(d[fa[y][i]] >= d[x])
        {
            y = fa[y][i];
        }
    }
    if(x == y) return x;
    for(int i = t; i >= 0; i--)
    {
        if(fa[y][i] != fa[x][i])
        {
            y = fa[y][i];x = fa[x][i];
        }
    }
    return fa[x][0];
}

int dist(int x,int y)
{
    return d[x]+d[y]-2*d[lca(x,y)];
}

struct node
{
    int x,y;
}a[maxn];

int ans[maxn],pre[maxn];

vector<pii> vt;

int find(int x)
{
    return pre[x]==x?x:pre[x]=find(pre[x]);
}

int dis[maxn];
bool vis[maxn];

int que[maxn];

void spfa(int u)
{
    for(int i = 1; i <= n; i++) 
    {
        vis[i] = 0;
    }
    int h = 1,r = 1;
    dis[u] = 0;que[1] = u;vis[u] = 1;
    while(h <= r)
    {
        u = que[h++];
        for(int i = head[u]; i ; i = Next[i])
        {
            int v = to[i];
            if(vis[v]) continue;
            dis[v] = dis[u]+1;
            vis[v] = 1;
            que[++r] = v;
        }
    }
    for(int i = 1; i <= q; i++) 
    {
        ans[i] = min(ans[i],dis[a[i].x]+dis[a[i].y]);
    }
}

map<int,bool> mp;

signed main()
{
    n = read(),m = read();
    for(int i = 1; i <= n; i++) 
    {
        pre[i] = i;
    }
    for(int i = 1,u,v; i <= m; i++) 
    {
        u = read(),v = read();
        if(find(u) == find(v))
        {
            vt.push_back({u,v});
            continue;
        }
        add(u,v);
        add(v,u);
        pre[find(u)] = find(v);
    }
    dfs(1,0);
    for(auto i : vt)
    {   
        add(i.first,i.second);
        add(i.second,i.first);
    }
    q = read();
    for(int i = 1; i <= q; i++) 
    {
        a[i].x = read(),a[i].y = read();
        ans[i] = dist(a[i].x,a[i].y);
    }
    for(auto i : vt)
    {
        if(!mp[i.first])
        {
            mp[i.first] = 1;
            spfa(i.first);
        }
        if(!mp[i.second])
        {
            mp[i.second] = 1;
            spfa(i.second);
        }
    }
    for(int i = 1; i <= n; i++) 
    {
        print(ans[i]);
        putchar('\n');
    }
    return 0;
}