Many Lamps
什么搞笑比赛,会 F 不会 DE。
贪就可以。
深搜到某个节点枚举它接的边时,如果自己没有点亮就激活这条边,总点亮的灯泡数增加 。如果所有边都遍历了自己还是灭着的,就激活一次和父亲连的边,点亮自己熄灭父亲。由于父亲计入自己时一定点亮自己了,因此父亲必定是亮着的状态,因此点亮的灯泡数量不会变化。对每个连通块都搜一次,若剩 个灯泡没有点亮输出 No
(显然一次操作只有三种结果:灯泡数 ,灯泡数不变,灯泡数 )。若点亮数量达到条件就按照记录下来的历史输出就好。
#include<bits/extc++.h>
using namespace std;
namespace pbds=__gnu_pbds;
using ui=unsigned int;
using uli=unsigned long long int;
using li=long long int;
struct node{size_t next,id;};
void dfs(size_t p,size_t fa,size_t faid,size_t& k,vector<bool>& vis,vector<bool>& colored,vector<vector<node>> const& mp,vector<size_t>& ans){
if (k==1){cout<<"No";exit(0);}
if (k==0){
cout<<"Yes\n"<<ans.size()<<'\n';
for (size_t i:ans) cout<<i+1<<' ';
exit(0);
}
vis[p]=true;
for (node i:mp[p]) if (!vis[i.next]){
if (!colored[p]){
ans.push_back(i.id);
if (!colored[i.next]) k-=2;
colored[p]=colored[i.next]=true;
}
dfs(i.next,p,i.id,k,vis,colored,mp,ans);
}
if (!colored[p]&&~fa){
ans.push_back(faid);
colored[fa]=false;
}
}
int main(void){
ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
size_t n,m,k;cin>>n>>m>>k;
vector<vector<node>> mp(n);
for (size_t i=0;i<m;++i){
size_t a,b;cin>>a>>b;--a,--b;
mp[a].push_back({b,i}),mp[b].push_back({a,i});
}
vector<bool> vis(n),colored(n);
vector<size_t> ans;
for (size_t i=0;i<n;++i) if (!vis[i]) dfs(i,~0,~0,k,vis,colored,mp,ans);
cout<<"No";
return 0;
}