Codeforces 841D Leha and another game about graph 构造

题意:n个点m条边的图,每个顶点有值d[i](0,1,-1),可以有重边或者环(无自环)
n,m<=3e5.问是否能删除某些边,使得剩下的定点i满足要么d[i]=-1或者deg[i]%2=d[i].
输出保留下来的边的编号.

首先图的度数和为偶数 若没有d[i]=-1&&d[i]之和为odd 则肯定无解
否则一定能构造:dfs生出一棵树.从叶子结点开始操作.
若当前结点d[u]==0 则说明u已经满足条件 不需要添加u-par[u]这条边.

若当前结点d[u]==1 则需要加上u-par[u]这条边.则d[u]满足条件,改变d[par[u]]其状态,操作过程中度数和总是保持even.一定有解.

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> ii;
const int N=4e5+5;
int n,m,d[N],vis[N];
vector<ii> e[N];
vector<int> ans;
bool dfs(int u)
{
	vis[u]=1;
	for(int i=0;i<e[u].size();i++)
	{
		int v=e[u][i].first;
		if(vis[v])	continue;
		if(dfs(v))
		{
			ans.push_back(e[u][i].second);	
			d[v]=0;//
			d[u]^=1;
		}	
	}
	return d[u];
}
int main()
{
	cin>>n>>m;
	int sum=0,rt=-1;
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&d[i]);
		sum+=(d[i]==1);
		if(d[i]==-1)
			rt=i;
	}
	int u,v;
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&u,&v);
		e[u].push_back(ii(v,i));
		e[v].push_back(ii(u,i));
	}
	if(sum%2 && rt==-1)
	{
		puts("-1");
		return 0;
	}
	if(sum%2)	d[rt]=1;
	else rt=1;
	for(int i=1;i<=n;i++)
	{
		if(d[i]==-1)
			d[i]=0;
	}
	dfs(rt);
	cout<<ans.size()<<endl;
	for(int i=0;i<ans.size();i++)
		printf("%d ",ans[i]);
	printf("\n");
	
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值