- P206's solution
P206's Solution
- 2025-10-5 22:08:42 @
首先,可以使用 BFS 计算不瞬移的答案。
假设最后一次瞬移到达了 点,当然 。
这意味着编号 的所有点都必须经过一遍。此时到达 点的总代价将至少是 。
而如果从 出发就一直瞬移,直到到达 ,那么就能达到这个最小的代价。
令 代表不瞬移,仅从给定边走,从 到 的最短路径长度,令 代表最后一次瞬移到达 的情况下,从 到 的最小代价。
枚举 ,答案就是 的最小值。
快速计算 dis,则只需要一次 bfs 预处理。
时间复杂度 。
std
#include <bits/stdc++.h>
using namespace std;
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define REP(i,a,b) for(int i=a;i>=b;i--)
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
#define gc getchar()
#define pc putchar
#define pln pc(10);
#define eb emplace_back
template<class T>
void ckmx(T& a,T b){
a=max(a,b);
}
template<class T>
void ckmn(T& a,T b){
a=min(a,b);
}
template<class T>
T gcd(T a,T b){
return !b?a:gcd(b,a%b);
}
template<class T>
T lcm(T a,T b){
return a/gcd(a,b)*b;
}
template<class T>
void read(T& x){
x=0;
int f=1;
char ch=gc;
while(!isdigit(ch)){
if(ch=='-')f=-1;
ch=gc;
}
while(isdigit(ch)){
x=(x<<1)+(x<<3)+(ch^48);
ch=gc;
}
x*=f;
}
template<class T>
void wrint(T x){
if(x>=10)wrint(x/10);
pc(x%10^48);
}
const int maxn=2e5+5;
int n,m,s,t;
vi g[maxn];
int dis[maxn];
void solve(int id_of_testcase){
read(n);
read(m);
read(s);
read(t);
FOR(i,1,m){
int u,v;
read(u);
read(v);
g[u].eb(v);
g[v].eb(u);
}
FOR(i,0,n-1)dis[i]=1e9;
queue<int> q;
dis[t]=0;
q.push(t);
while(!q.empty()){
int u=q.front();
q.pop();
for(int& v:g[u]){
if(dis[v]>dis[u]+1){
dis[v]=dis[u]+1;
q.push(v);
}
}
}
int ans=dis[s];
FOR(i,0,n-1){
int ds=dis[i]+i+1;
if(i>=s)ds--;
ckmn(ans,ds);
}
wrint(ans);
pln
FOR(i,0,n-1){
g[i].clear();
}
}
int main(){
int T;
read(T);
FOR(_,1,T){
solve(_);
}
return 0;
}
验题人 @Tiffake 的代码:
#include<bits/stdc++.h>
#define int long long
#define pair pair<int,int>
#define fst first
#define snd second
using namespace std;
const int N=3e5+1;
int T,n,m,s,t,x,y,ans,d[N];
priority_queue<pair,vector<pair>,greater<pair>>q;
vector<int>v[N];
bitset<N>vis;
inline void dijkstra(){
for(int i=0;i<n;i++)d[i]=INT_MAX>>2;
d[t]=0,q.push({0,t});
while(!q.empty()){
int u=q.top().snd;q.pop();
if(vis[u])continue;
vis[u]=1;
for(int i:v[u]){
if(d[i]>d[u]+1){
d[i]=d[u]+1;
q.push({d[i],i});
}
}
}
}
signed main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>T;
while(T--){
cin>>n>>m>>s>>t,ans=INT_MAX,vis.reset();
for(int i=0;i<n;i++)v[i].clear();
while(m--)cin>>x>>y,v[x].push_back(y),v[y].push_back(x);
dijkstra();
for(int i=0;i<s;i++)ans=min(ans,d[i]+i+1);
for(int i=s+1;i<n;i++)ans=min(ans,d[i]+i);
cout<<min(ans,d[s])<<'\n';
}
return 0;
}
验题人 @Lastkismet 的代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef __int128 i128;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<int,ll> pil;
typedef pair<ll,int> pli;
template<typename T> using vec=vector<T>;
template<typename T> using grheap=priority_queue<T>;
template<typename T> using lrheap=priority_queue<T,vector<T>,greater<T>>;
#define fir first
#define sec second
#define pub push_back
#define pob pop_back
#define puf push_front
#define pof pop_front
#define chmax(a,b) a=max(a,b)
#define chmin(a,b) a=min(a,b)
#define rep(i,x,y) for(int i=(x);i<=(y);i++)
#define per(i,x,y) for(int i=(x);i>=(y);i--)
#define repl(i,x,y) for(int i=(x);i<(y);i++)
#define file(f) freopen(#f".in","r",stdin);freopen(#f".out","w",stdout);
struct mint {
int x,mod;
inline mint(int o=0,int p=998244353) {x=o;mod=p;}
inline mint & operator=(ll o){return x=o%mod,(x+=mod)>=mod&&(x-=mod),*this;}
inline mint & operator+=(mint o){return (x+=o.x)>=mod&&(x-=mod),*this;}
inline mint & operator-=(mint o){return (x-=o.x)<0&&(x+=mod),*this;}
inline mint & operator*=(mint o){return x=(ll)x*o.x%mod,*this;}
inline mint & operator^=(ll b){mint res(1);for(;b;b>>=1,*this*=*this)if(b&1)res*=*this;return x=res.x,*this;}
inline mint & operator^=(mint o){return *this^=o.x;}
inline mint & operator/=(mint o){return *this*=(o^=(mod-2));}
inline mint & operator++(){return *this+=1;}
inline mint & operator--(){return *this-=1;}
inline mint operator++(int o){mint res=*this;return *this+=1,res;}
inline mint operator--(int o){mint res=*this;return *this-=1,res;}
friend inline mint operator+(mint a,mint b){return a+=b;}
friend inline mint operator-(mint a,mint b){return a-=b;}
friend inline mint operator*(mint a,mint b){return a*=b;}
friend inline mint operator/(mint a,mint b){return a/=b;}
friend inline mint operator^(mint a,ll b){return a^=b;}
friend inline mint operator^(mint a,mint b){return a^=b;}
friend inline bool operator<(mint a,mint b){return a.x<b.x;}
friend inline bool operator>(mint a,mint b){return a.x>b.x;}
friend inline bool operator<=(mint a,mint b){return a.x<=b.x;}
friend inline bool operator>=(mint a,mint b){return a.x>=b.x;}
friend inline bool operator==(mint a,mint b){return a.x==b.x;}
friend inline istream & operator>>(istream &in,mint &o){ll x;return in>>x,o=x,in;}
friend inline ostream & operator<<(ostream &ot,mint o){return ot<<o.x,ot;}
};
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int N=2e5+5;
int n,m,s,t;
int dis[2][N];
vec<int> g[N];
void bfs(int be,int kd){
queue<int> q;
q.push(be);
while(!q.empty()){
int now=q.front();q.pop();
for(auto nxt:g[now])if(dis[kd][nxt]>dis[kd][now]+1){
dis[kd][nxt]=dis[kd][now]+1;
q.push(nxt);
}
}
}
void solve(){
cin>>n>>m>>s>>t;
repl(i,0,n)g[i].clear(),dis[0][i]=dis[1][i]=inf;
rep(i,1,m){
int u,v;cin>>u>>v;
g[u].pub(v);
g[v].pub(u);
}
dis[0][s]=dis[1][t]=0;
bfs(s,0);bfs(t,1);
int ans=inf;
repl(i,0,n)chmin(ans,dis[1][i]+min(dis[0][i],i+(i<=s)));
if(ans==inf)ans=-1;
cout<<ans<<"\n";
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int t;cin>>t;
while(t--)solve();
return 0;
}