视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
codeforcesRound#259(div2)E解题报告
2020-11-09 08:02:32 责编:小采
文档


解法:

首先我们可以明确一点,这就是一个图的遍历,找一个点,设为起点,建立一个搜索遍历树,对于树每一个点,我们完全可以控制奇偶性,假设:

目前访问的点为v,父节点为fa,如若点v不符合当前的奇偶性,则就让父节点到v绕一次,这样 odd[v] ^= 1, fa[v] ^= 1,这样我们可以完全保证完全控制子节点,将不符合要求的奇偶性调整成符合要求的奇偶性。同时父节点的奇偶性也在改变。

通过上述的操作,我们可以每次保证子节点的奇偶性符合要求,然而父节点的奇偶性如若不符合要求,则可以通过调整父节点 与 父节点的父节点来调整奇偶性,这样我们就可以奇偶性传递,最终传递到根节点。根节点如若不符合该如何调整呢?由于我们是走遍历树,到达叶节点还要回来的,意味着我们要走至少两次根节点,一次是出发,一次是最后一次回归。我们可以将根节点 r1 调整到根节点的其中一个子节点r2,使得奇偶性再次得到调整

代码:

#include 
#include 
#define N_max 123456

using namespace std;

int n, m, fa[N_max], want[N_max];
int Odd_n, Odd_x, haveOdd[N_max];
vector  G[N_max], ans;

int getf(int x) {
	return (fa[x] == x) ? x : fa[x] = getf(fa[x]);
}
void addedge(int x, int y) {
	G[x].push_back(y);
}

void init() {
	scanf("%d%d", &n, &m);

	for (int i = 1; i <= n; i++) fa[i] = i;
	for (int i = 1; i <= m; i++) {
	int x, y;

	scanf("%d%d", &x, &y);

	int tmpx=getf(x);
	int tmpy=getf(y);
	if (tmpx != tmpy) {
	fa[tmpx] = tmpy;
	addedge(x, y);
	addedge(y, x);
	}
	}

	for (int i = 1; i <= n; i++) {
	scanf("%d", &want[i]);

	if (want[i]) haveOdd[getf(i)] = 1;
	}

	for (int i = 1; i <= n; i++)
	if (haveOdd[i]) {
	Odd_n++;
	Odd_x = i;
	}
}

void dfs(int now, int pre) {
	ans.push_back(now);
	want[now] ^= 1;

	for (int i = 0; i < G[now].size(); i++) {
	int nex = G[now][i];
	if (nex == pre) continue;

	dfs(nex, now);
	ans.push_back(now);
	want[now] ^= 1;

	if (want[nex]) {
	ans.push_back(nex);
	want[nex] ^= 1;
	ans.push_back(now);
	want[now] ^= 1;
	}
	}
}

void solve() {
	if (Odd_n == 0) {
	printf("0\n");
	return;
	}

	if (Odd_n > 1) {
	printf("-1\n");
	return;
	}

	dfs(Odd_x, -1);
	int x = 0;
	if (want[Odd_x]) x=1;

	printf("%d\n", ans.size() - x);
	for (int i = x; i < ans.size(); i++)
	printf("%d ", ans[i]);
}

int main() {
	init();
	solve();
}

下载本文
显示全文
专题