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
");
                break;
            }
            if(i==n){
                printf("YES
");
                printf("%d
",ans.size());
                for(auto x:ans){
                    printf("%d ",x);
                }
                printf("
");
            }
        }
    }
    return 0;
}

不摆烂了,写题
原文地址:https://www.cnblogs.com/hunxuewangzi/p/15242652.html