Atcoder abc 456 分层图+方向拓扑

https://atcoder.jp/contests/abc456/tasks/abc456_e

代码

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define ep emplace
#define pb push_back
#define all(a) a.begin(),a.end()
#define mod 998244353
#define MOD 1000000007
#define N 200010
//分层图+反向拓扑
void solve(){
    int n,m;cin>>n>>m;
    vector<vector<int>>g(n+1);
    vector<string>s(n+1);
    while(m--){
        int x,y;cin>>x>>y;
        g[x].push_back(y);
        g[y].push_back(x);
    }//建立边
    int w;cin>>w;
    vector<vector<int>>f(n+1,vector<int>(w));
    vector<vector<int>>h(n+1,vector<int>(w));
    //h[i][j]:时刻j位于节点i的时候,下一秒有多少个合法的移动选项,包括呆在原地和去可以去到的邻居
    for(int i=1;i<=n;i++){
        cin>>s[i];
        for(int j=0;j<w;j++){
            if(s[i][j]=='x')f[i][j]=1;
        }
    }//死掉的节点,已经是X的了
    for(int i=1;i<=n;i++){
        for(int j=0;j<w;j++){
            if(!f[i][j]){
                int prej=(j-1+w)%w;
                h[i][prej]++;
                for(int v:g[i]){
                    h[v][prej]++;
                }
            }
        }
    }//算出各个点下一步可以走的路数
    queue<pair<int,int>>q;
    for(int i=1;i<=n;++i){
        for(int j=0;j<w;++j){
            if(!f[i][j]&&h[i][j]==0){
                f[i][j]=1;q.push({i,j});
            }
        }
    }//把那些死胡同的点,也就是是o,但是下一步一个o也走不到的点push到队列里
    while(!q.empty()){
        int u=q.front().first;//城市
        int t=q.front().second;//时间
        int pret=(q.front().second-1+w)%w;
        q.pop();
        if(!f[u][pret]&&--h[u][pret]==0){
            f[u][pret]=1;
            q.push({u,pret});
        }
        for(int v:g[u]){
            if(!f[v][pret]&&--h[v][pret]==0){
                f[v][pret]=1;
                q.push({v,pret});
            }
        }
    }//类似反向拓扑
    bool flag=false;
    for(int i=1;i<=n;i++)if(f[i][0]==0)flag=true;
    //如果在0时刻有以某个f[i][0]是0,说明从这个点出发有一条成环的每一天都可以是放假的路线
    //为什么是这样呢:因为如果这条路不是有环的而是有尽头的,那么这个尽头就会呗标记为1,然后从后往前所有的都会被标记为1
    //就没有会被标记为0的
    if(flag)cout<<"Yes"<<endl;
    else cout<<"No"<<endl;
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    int t;cin>>t;
    while(t--)solve();
    return 0;
}
posted @ 2026-05-03 16:33  Time_q  阅读(31)  评论(0)    收藏  举报