题解 CF840B Leha and another game about graph
构造题。
首先判断无解。每选一条边贡献两个度数,所以如果没有 的点,且度数和为奇数,那么无解。
接下来考虑构造。我们考虑从图中扣下来一棵树(dfs 树),如果度数为奇数,令 的点为根,否则随便选一个。
定义 表示第 个节点是否需要与父亲连边, 表示不用, 表示用。然后对于当前点 ,向所有满足 的儿子连边,容易证明这是正确的。
因为,如果根为 的点,那么根怎么连都行;否则,根据反证法,如果根还需要连边,而其他节点都已连好,那么总度数为奇数,矛盾。
复杂度 。
code:
#include<bits/stdc++.h>
using namespace std;
const int N=3e5+5;
int n,m,d[N],tp[N],vis[N];
struct node{
int v,id;
node(int v=0,int id=0):v(v),id(id){}
};
vector<node>adj[N];
vector<int>ans;
void dfs(int u){
int s=d[u];vis[u]=1;
for(int i=0;i<adj[u].size();++i){
int v=adj[u][i].v,id=adj[u][i].id;if(vis[v])continue;
dfs(v);
if(tp[v])s^=1,ans.push_back(id);
}
if(d[u]!=-1)tp[u]=s;
}
int main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin>>n>>m;
int rt=1,f=0,s=0;
for(int i=1;i<=n;++i){
cin>>d[i];
if(d[i]==-1)rt=f=i;
else s^=d[i];
}
for(int i=1;i<=m;++i){
int u,v;cin>>u>>v;
adj[u].push_back(node(v,i));
adj[v].push_back(node(u,i));
}
if(!f&&s)cout<<-1<<endl;
else{
dfs(rt);sort(ans.begin(),ans.end());
cout<<ans.size()<<endl;
for(int i=0;i<ans.size();++i)cout<<ans[i]<<endl;
}
return 0;
}
本文作者:HQJ2007
本文链接:https://www.cnblogs.com/HQJ2007/p/17561370.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通