2 条题解
-
0
首先,可以使用 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; } -
0
首先,可以使用 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; }
- 1
信息
- ID
- 203
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 6
- 标签
- 递交数
- 5
- 已通过
- 4
- 上传者