D. Strange Housing 題解(思維+染色)
阿新 • • 發佈:2021-09-08
題目連結
題目大意
這個題意好繞
就是一個\(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; }