『题解』Luogu P3556 [POI2013]MOR-Tales of seafaring
update on 2022/6/5 修改了一下代码。
题目大意
给 n 个点 m 条边无向图,每次询问两个点之间是否有长度为 d 的路径(不一定是简单路径)。
思路
使用 bfs 广搜。
题目求的路径长度 d 不一定为简单路径,意为可以重复走边。
可以重复走边,那么我们只需求出每个点的长度为奇数的最短路径和长度为偶数的最短路径。
为什么这么说呢?观察重复走边,就是你回去一次,再跑过来一次,那么每次要加上 2 长度。那么只需判断 d 是否比最短路径大且与最短路长度奇偶性相同。
如何求出奇数最短路和偶数最短路呢?利用拆点,将每个点拆成两个,分别表示到这个点且路径长度为奇数和偶数的路径长度。
广搜时从每个偶数点开始搜索,建立 dis,查询时可 O(1) 复杂度。
查询时,奇数和偶数情况都判断一下,如果 d 为奇数,就去奇数最短路径表中查询,如果奇数情况下的最短路径有,并且小于或等于 d 那么就有长度为 d 的路径。反之亦然。
代码
#include <iostream>
#include <queue>
using namespace std;
template<typename T=int>
inline T read(){
T X=0; bool flag=1; char ch=getchar();
while(ch<'0' || ch>'9'){if(ch=='-') flag=0; ch=getchar();}
while(ch>='0' && ch<='9') X=(X<<1)+(X<<3)+ch-'0',ch=getchar();
if(flag) return X;
return ~(X-1);
}
template<typename T=int>
inline void write(T X){
if(X<0) putchar('-'),X=~(X-1);
T s[20],top=0;
while(X) s[++top]=X%10,X/=10;
if(!top) s[++top]=0;
while(top) putchar(s[top--]+'0');
putchar('\n');
}
const int N=2e4+5,M=2e5+5;
struct edge{ // 链式前向星存图
int to,next;
}e[M];
int n,m,k,u,v,d;
int head[N],top;
int dis[N][N]; // dis[i][j]:i->j的最短路径长度
queue<int> q; // bfs所用队列
void add(int u,int v){ // 加边不多说
top++;
e[top].to=v;
e[top].next=head[u];
head[u]=top;
}
void bfs(int id){ // id 表示搜索的点的编号
// 广搜差不多是模板
q.push(id);
while(!q.empty()){
u=q.front();
q.pop();
for(int i=head[u]; i; i=e[i].next){ // 遍历,更新最短路径
v=e[i].to;
if(!dis[id][v]){ // 只 bfs 一次,首先被遍历的才是最短的
dis[id][v]=dis[id][u]+1; // 因为边权始终为 1,所以更新一次就行。
q.push(v);
}
}
}
}
int main(){
n=read(),m=read(),k=read();
while(m--){
u=read(),v=read();
add(u+n,v),add(v,u+n); // 拆点&建边(双向)
add(u,v+n),add(v+n,u);
}
for(int i=1; i<=n; i++) bfs(i); // 预处理 distance
while(k--){
u=read(),v=read(),d=read();
if(d&1 && dis[u][v+n]<=d && dis[u][v+n] // 奇数情况:查询u->v的奇数最短路
|| !(d&1) && dis[u][v]<=d && dis[u][v]) // 偶数情况:查询u->v的偶数最短路
puts("TAK"); // 如果最短路径小于等于要求路径,且两种情况满足任意一个,就OK
else puts("NIE"); // 否则输出 NIE
}
return 0;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】博客园携手 AI 驱动开发工具商 Chat2DB 推出联合终身会员
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步