求助一道较为经典的题目
  • 板块学术版
  • 楼主KK_lang
  • 当前回复1
  • 已保存回复1
  • 发布时间2023/12/13 17:24
  • 上次更新2023/12/13 20:02:27
查看原帖
求助一道较为经典的题目
548203
KK_lang楼主2023/12/13 17:24

rt,但是洛谷貌似没有原题,题目大意就是给定一张图求出有哪些线段被擦除之后整张图变为一个二分图

目前是痛苦 RE,求助大佬 qwq

#include<bits/stdc++.h>
using namespace std;

const int nr = 1e6 + 1;
int n, m, cnt, dep[nr], lg[nr], anc[nr][20], dif[nr][2], f[nr], size[nr];
struct Edge { int u, v; } e[nr];
bool inmst[nr], inans[nr];
vector<int> adj[nr];

int find(int x)
{
	if (f[x] == x) return x;
	return f[x] = find(f[x]);
}

void merge(int x, int y)
{
	int fx = find(x), fy = find(y);
	if (size[x] > size[y]) swap(x, y);
	f[fx] = fy, size[fy] += size[fx];
}

void init(int x, int ft)
{
	dep[x] = dep[ft] + 1;
	anc[x][0] = ft;
	for (int i = 1; i <= lg[dep[x]]; i++)
		anc[x][i] = anc[anc[x][i - 1]][i - 1];
	for (int i = 0; i < adj[x].size(); i++)
		if (adj[x][i] != ft) init(adj[x][i], x);
}

int lca(int x, int y)
{
	if (dep[x] < dep[y]) swap(x, y);
	while (dep[x] > dep[y]) x = anc[x][lg[dep[x] - dep[y]]];
	if (x == y) return x;
	for (int i = lg[dep[x]]; i >= 0; i--)
		if (anc[x][i] != anc[y][i]) x = anc[x][i], y = anc[y][i];
	return anc[x][0];
}

int dis(int x, int y, int _lca)
{ return dep[x] + dep[y] - 2 * dep[_lca] + 1; }

void dfs(int x, int ft)
{
	for (int i = 0; i < adj[x].size(); i++)
		if (adj[x][i] != ft)
		{
			dfs(adj[x][i], x);
			dif[x][0] += dif[adj[x][i]][0];
			dif[x][1] += dif[adj[x][i]][1];
		}
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr), cout.tie(nullptr);
	cin >> n >> m;
	for (int i = 1; i <= m; i++)
	{
		cin >> e[i].u >> e[i].v;
		adj[e[i].u].push_back(e[i].v);
		adj[e[i].v].push_back(e[i].u);
	}
	for (int i = 1; i <= n; i++) f[i] = i, size[i] = 1;
	for (int i = 1; i <= m; i++)
		if (find(e[i].u) != find(e[i].v))
		{
			merge(e[i].u, e[i].v);
			inmst[i] = true;
		}
	for (int i = 1; i <= m; i++)
		if (inmst[i]) adj[e[i].u].push_back(e[i].v), adj[e[i].v].push_back(e[i].u);
	lg[0] = -1;
	for (int i = 1; i <= n; i++) lg[i] = lg[i >> 1] + 1;
	init(1, 0);
	for (int i = 1; i <= m; i++)
		if (!inmst[i])
		{
			int _lca = lca(e[i].u, e[i].v);
			int _dis = dis(e[i].u, e[i].v, _lca);
			if (_dis % 2 == 0) dif[e[i].u][0]++, dif[e[i].v][0]++, dif[_lca][0] -= 2;
			else dif[e[i].u][1]++, dif[e[i].v][1]++, dif[_lca][1] -= 2, cnt++;
		}
	dfs(1, 0);
	if (cnt == 0)
	{
		cout << m << '\n';
		for (int i = 1; i <= m; i++) cout << i << " ";
		return 0;
	}
	int ans = 0;
	for (int i = 1; i <= m; i++)
	{
		int pos = (dep[e[i].u] > dep[e[i].v] ? e[i].u : e[i].v);
		if ((inmst[i] || !inmst[i] && cnt == 1) && dif[pos][0] == 0 && dif[pos][1] == cnt) ans++, inans[i] = true;
	}
	cout << ans << '\n';
	for (int i = 1; i <= m; i++) if (inans[i]) cout << i << " ";
	return 0;
}
2023/12/13 17:24
加载中...