1. 程式人生 > 其它 >D. Strange Housing 題解(思維+染色)

D. Strange Housing 題解(思維+染色)

題目連結

題目大意

這個題意好繞

就是一個\(n\)個點 \(m\)條雙向邊的圖

你要對一些點進行標記,並且標記的點不能直接相鄰

如果兩個相鄰的點都沒有被標記,那麼這兩個點的邊則被刪除

看最後能否構成一個連通圖

題目思路

就是如果題目不連通那就是NO,否則就是YES

染色方案就是類似於bfs層層染色

保證不能相鄰的點都被標記

程式碼

#include<bits/stdc++.h>
#define fi first
#define se second
#define debug cout<<"I AM HERE"<<endl;
using namespace std;
typedef long long ll;
const int maxn=1e6+5,inf=0x3f3f3f3f,mod=1e9+7;
const double eps=1e-6;
int n,m;
vector<int> g[maxn];
vector<int> ans;
int vis[maxn];
signed main(){
    int _;cin>>_;
    while(_--){
        cin>>n>>m;
        ans.clear();
        for(int i=1;i<=n;i++){
            vis[i]=0;
            g[i].clear();
        }
        for(int i=1,u,v;i<=m;i++){
            cin>>u>>v;
            g[u].push_back(v);
            g[v].push_back(u);
        }
        queue<int> que;
        que.push(1);
        vis[1]=1;
        ans.push_back(1);
        // 0沒有染色
        // 1黑色
        // 2白色
        while(!que.empty()){
            int x=que.front();
            que.pop();
            for(auto u:g[x]){
                if(vis[u]) continue;
                if(vis[x]==1){
                    vis[u]=2;
                }else{
                    bool flag=1;
                    for(auto v:g[u]){
                        flag=(flag&(vis[v]!=1));
                    }
                    if(flag){
                        vis[u]=1;
                        ans.push_back(u);
                    }else{
                        vis[u]=2;
                    }
                }
                que.push(u);
            }
        }
        for(int i=1;i<=n;i++){
            if(vis[i]==0){
                printf("NO\n");
                break;
            }
            if(i==n){
                printf("YES\n");
                printf("%d\n",ans.size());
                for(auto x:ans){
                    printf("%d ",x);
                }
                printf("\n");
            }
        }
    }
    return 0;
}

不擺爛了,寫題