打卡信奥刷题(3294)用C++实现信奥题 P9026 [CCC 2021 S4] Daily Commute
P9026 [CCC 2021 S4] Daily Commute
题目描述
已知有 N N N 个地铁站,你家在 1 1 1,学校在 N N N。
有 W W W 条单向人行道。经过需要一分钟。
此外还有一条环形地铁线路,依次经过 S 1 , S 2 , ⋯ , S N S_1,S_2,\cdots,S_N S1,S2,⋯,SN,且保证 S 1 = 1 S_1=1 S1=1。每天有且仅有一辆地铁在 0 0 0 时刻从 S 1 S_1 S1 出发,并且恰好在第 i i i 分钟到达 S i S_i Si。
在接下来 D D D 天中:
- 交换 S X i S_{X_i} SXi 和 S Y i S_{Y_i} SYi。注意修改是永久的。
- 查询从 1 1 1 到 N N N 的最短用时。你出发时地铁在 1 1 1。
输入格式
第一行: N , W , D N,W,D N,W,D。
接下来 W W W 行: A i , B i A_i,B_i Ai,Bi 表示单向人行道。
接下来一行 N N N 个数: S S S。
接下来 D D D 行: X i , Y i X_i,Y_i Xi,Yi,保证 2 ≤ X i , Y i ≤ N , X i ≠ Y i 2\leq X_i,Y_i\leq N,X_i\neq Y_i 2≤Xi,Yi≤N,Xi=Yi。
输出格式
D D D 行,每天的答案。
输入输出样例 #1
输入 #1
4 3 3
1 2
3 4
4 1
1 4 3 2
3 4
4 2
3 2
输出 #1
1
2
3
说明/提示
3 ≤ N ≤ 200000 , 0 ≤ W ≤ 200000 , 1 ≤ D ≤ 200000 3\leq N\leq 200000,0\leq W\leq 200000,1\leq D\leq 200000 3≤N≤200000,0≤W≤200000,1≤D≤200000
译自 CCC2021 S4。
请注意常数。
C++实现
#include<stdio.h>
#include<queue>
#define N 222222
#define pr pair<int,int>
using namespace std;
inline char nc(){
static char buf[99999],*l,*r;
return l==r&&(r=(l=buf)+fread(buf,1,99999,stdin),l==r)?EOF:*l++;
}
inline void read(int&x){
char c=nc();for(;c<'0'||'9'<c;c=nc());
for(x=0;'0'<=c&&c<='9';x=(x<<3)+(x<<1)+(c^48),c=nc());
}
inline void pc(const char&c){
static char buf[99999],*r=buf;
(!c||(*r++=c,r==buf+99999))&&(fwrite(buf,1,r-buf,stdout),r=buf);
}
inline void pi(const int&x){if(x>9)pi(x/10);pc(x%10+'0');}
int n,m,d,s[N],a[N],h[N],e[N],nxt[N],dis[N];
priority_queue<pr,vector<pr>,greater<pr> >qwq;deque<int>q;
main(){
read(n);read(m);read(d);
for(int i=1,u,v;i<=m;++i)read(u),read(v),--u,--v,
e[i]=u,nxt[i]=h[v],h[v]=i;
for(int i=0,x;i<n;read(s[i]),a[--s[i]]=i,dis[i++]=1<<30);
q.emplace_back(n-1);dis[n-1]=0;
for(int i;q.size();) {
i=q.front();q.pop_front();
for(int j=h[i];j;j=nxt[j])if(dis[e[j]]>>30)
dis[e[j]]=dis[i]+1,q.emplace_back(e[j]);
}
for(int i=0;i<n;++i)qwq.emplace(dis[i]+a[i],i);
for(int u,v;d--;pi(qwq.top().first),pc('\n')) {
read(u);read(v);--u;--v;
swap(s[u],s[v]);
u=s[u];v=s[v];
swap(a[u],a[v]);
qwq.emplace(dis[u]+a[u],u);qwq.emplace(dis[v]+a[v],v);
for(;qwq.top().first^dis[qwq.top().second]+a[qwq.top().second];
qwq.pop());
}
pc(0);
}

后续
接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)