题解:luogu P15547 「Stoi2037」白色风车
题目链接:https://www.luogu.com.cn/problem/P15547
分类讨论,如果 \(x,y\) 之间不连通,那么输出 No。
因为只能回头一次,如果要无限移动,必然在 \(x,y\) 所在连通块内有环。
如果 \(x,y\) 要在同一条边上,那么它们之间的路径长度一定是奇数。所以如果有奇环输出 Yes,如果没有在判断路径长度。
考虑从 \(x\) 出发,判断是否可达 \(y\),是否有环。给图染色,如果两点颜色相同说明之间路径长度为偶数,输出 No,否则输出 Yes。
时间复杂度 \(O(n+m)\)。
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+5;
int T, n, m, vis[N], col[N];
bool flag, has_ring;
vector<int> g[N];
inline void dfs(int x, int fa, int nowc){
vis[x] = 1, col[x] = nowc;
for(int y : g[x]){
if(vis[y]){
if(col[y] != nowc ^ 1) flag = true;
if(y != fa) has_ring = true;
continue;
}
dfs(y, x, nowc ^ 1);
}
}
signed main(){
ios::sync_with_stdio(0);
int id; cin >> id; cin >> T;
while(T--){
int x, y; flag = false, has_ring = false;
cin >> n >> m >> x >> y;
for(int i = 1; i <= n; i++) g[i].clear(), vis[i] = 0, col[i] = 0;
for(int i = 1; i <= m; i++){
int u, v; cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
dfs(x, 0, 1);
if(!vis[y]){ cout << "No\n"; continue; }
if(!has_ring){ cout << "No\n"; continue; }
if(flag){ cout << "Yes\n"; continue; }
if(col[x] != col[y]){ cout << "Yes\n"; continue; }
else { cout << "No\n"; continue; }
}
return 0;
}

浙公网安备 33010602011771号