题意
给一个连通图,每次询问两点间最短路。
分析
首先我们取联通的条边,利用
,处理出询问的答案。
然后我们最多还剩下条边,我们对这些边的点跑
,处理出所有点到该点的距离,
然后遍历所有的询问,更新答案。
时间有点紧
#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;
} 
京公网安备 11010502036488号