CF1860E
拿到这种题很难不往最短路上面去想,于是得出:
相邻两个连一条边权为
这样做完之后就遇到了一个问题,如何统计答案呢?
#include<bits/stdc++.h>
#define int long long
#define FastIO ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define I using
#define AK namespace
#define CSPS2026 std
I AK CSPS2026;
const int maxn=1e6+10,maxm=8e4+10,maxqwq=700,mod=998244353,inf=1e9;
int t,n,m,x,y,z,u,v,w,ans,arr[maxn],vis[maxn],dis[maxqwq][maxm];
char s[maxn];
vector<pair<int,int> >e[maxn];
deque<int>q;
int calc(char c,char d)
{
return (c-'a')*26+(d-'a');
}
void bfs(int s)
{
for(int i=1;i<=m+x;i++)
{
dis[s][i]=inf;
vis[i]=0;
}
q.push_front(s+m);
dis[s][s+m]=0;
while(!q.empty())
{
int u=q.front();
q.pop_front();
if(vis[u])continue;
vis[u]=1;
for(auto v:e[u])
{
if(dis[s][v.first]>dis[s][u]+v.second)
{
dis[s][v.first]=dis[s][u]+v.second;
if(vis[v.first])continue;
if(!v.second)q.push_front(v.first);
else q.push_back(v.first);
}
}
}
return;
}
signed main()
{
FastIO;
cin>>(s+1)>>n;
m=(int)(strlen(s+1));
x=26*26;
for(int i=1;i<m;i++)
{
v=calc(s[i],s[i+1]);
if(i!=1) e[i].push_back({i-1,2});
if(i!=m-1) e[i].push_back({i+1,2});
e[i].push_back({v+m,1});
e[v+m].push_back({i,1});
}
for(int i=0;i<x;i++)bfs(i);
for(int i=1;i<=n;i++)
{
cin>>u>>v;
if(u>v)swap(u,v);
ans=v-u;
for(int i=0;i<x;i++)ans=min(ans,(dis[i][u]+dis[i][v])>>1);
cout<<ans<<"\n";
}
return 0;
}