题解: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;
}
posted @ 2026-08-22 17:13  Antony_pico  阅读(2)  评论(0)    收藏  举报