专栏文章
题解:P13001 [GCJ 2022 Finals] Wonderland Chase
P13001题解参与者 2已保存评论 1
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @minuj92g
- 此快照首次捕获于
- 2025/12/02 08:35 3 个月前
- 此快照最后确认于
- 2025/12/02 08:35 3 个月前
这题只需要搞明白一件事情,剩下的就是一些很简单的图论操作了。
什么时候追不到,能跑掉呢?很显然 的次数意思是告诉我们永远都追不上才能跑掉。只有两种情况符合这种要求:
- Alice 与红心皇后不在一个连通块,这样皇后无论如何也跑步过来。
- Alice 能赶在被抓伤之前跑进一个环。因为一旦在环里面,Alice 无论如何都有一条路可以走。
否则,Alice 一定就会被追上。这时只需要找到一个点,使得Alice 能在皇后赶到之前抵达,最大化皇后赶到的时间即可。
实现起来的话,先标记所有处于环内的点。由于这是无向图,我们不用什么 tarjan 之类的算法,只需要依次移除所有度为 的点即可。
接下来就是跑两次 dijkstra,记录所有点距离皇后与 Alice 分别有多远,然后遍历所有点。若点处于环内,且距离 Alice 比距离皇后近,则代表 Alice 安全。否则若不在环但仍然离 Alice 更近,则更新一下答案。若皇后距离 Alice 所在的点为无穷大,则 Alice 也是安全的。
最后注意乘以 ,因为皇后动一步 Alice 也得动一步。
以下代码是处理每一个测试点的代码,注意多测清空。
CPPcin>>j>>c>>a>>q;
while (c--){
int u,v;
cin>>u>>v;
adj[u].push_back(v);
adj[v].push_back(u);
deg[u]++;
deg[v]++;
}
for (int i=1;i<=j;i++) alice[i]=queen[i]=MAXN;
queue<pair<int,int>> qq;
qq.push({0,a});
while (qq.size()){
auto qf=qq.front();
qq.pop();
if (alice[qf.second]!=MAXN) continue;
alice[qf.second]=qf.first;
for (int i:adj[qf.second]) qq.push({qf.first+1,i});
}
qq.push({0,q});
while (qq.size()){
auto qf=qq.front();
qq.pop();
if (queen[qf.second]!=MAXN) continue;
queen[qf.second]=qf.first;
for (int i:adj[qf.second]) qq.push({qf.first+1,i});
}
for (int i=1;i<=j;i++) cycle[i]=1;
queue<int> qqq;
for (int i=1;i<=j;i++){
if (deg[i]==1) {
qqq.push(i);
}
}
while (qqq.size()){
int qf=qqq.front();
qqq.pop();
vis[qf]=1;
cycle[qf]=0;
for (int i:adj[qf]) {
if (!vis[i]) {
deg[i]--;
if (deg[i]==1) qqq.push(i);
}
}
}
int ans=0;
for (int i=1;i<=j;i++){
if (alice[i]==MAXN) continue;
if (alice[i]<queen[i]) ans=max(ans,queen[i]);
if ((cycle[i]&&alice[i]<queen[i])||(alice[i]!=MAXN&&queen[i]==MAXN)){
cout<<"SAFE\n";
return ;
}
}
cout<<ans*2<<"\n";
相关推荐
评论
共 1 条评论,欢迎与作者交流。
正在加载评论...