ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

图染色

2022-06-11 12:00:57  阅读:173  来源: 互联网

标签:int 染色 d% 大点 add include


图染色

根号分治

图染色 - 题目 - Daimayuan Online Judge

图染色问题一般可用,树染色可用 dp 等方法

  1. 设一个阈值 M
  2. 度数大于 M 的点可设为大点,<= M 的设为小点

查询

  1. 若为小点,直接暴力枚举邻居,最多枚举 M 个
  2. 若为大点,不能暴力枚举,可考虑在修改的时候就算出来大点的答案

修改

​ 可预处理出每个点的大点邻居,存到 B 数组里,当反转这个点时,直接更新它的大点邻居,复杂度为 \(O(\frac {边数}M)\)

​ 不能也更新小点,因为小点邻居可能很多

设 M 为 \(\sqrt {边数}\) 即可

#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>

using namespace std;
#define endl "\n"

typedef long long ll;
typedef pair<int, int> PII;

const int N = 2e5 + 10, M = 500;
int n, m, q;
vector<vector<int> > G(N), B(N);
bool big[N];
int col[N], ans[N];
void add(int u, int v)
{
	G[u].push_back(v);
}
int main()
{
	scanf("%d%d%d", &n, &m, &q);
	while(m--)
	{
		int u, v;
		scanf("%d%d", &u, &v);
		add(u, v), add(v, u);
	}
	for (int i = 1; i <= n; i++)
		if (G[i].size() > M) big[i] = true;

	for (int u = 1; u <= n; u++)
	{
		for (auto v : G[u])
		{
			if (big[v])
				B[u].push_back(v);
		}
	}
	while(q--)
	{
		int op, x;
		scanf("%d%d", &op, &x);
		if (op == 1)
		{
			col[x] ^= 1;
			for (int y : B[x])
			{
				if (col[x])
					ans[y]++;
				else
					ans[y]--;
			}
		}
		else
		{
			if (big[x])
				printf("%d\n", ans[x]);
			else
			{
				int cnt = 0;
				for (int y : G[x])
					cnt += col[y];
				printf("%d\n", cnt);
			}
		}
	}
    return 0;
}

标签:int,染色,d%,大点,add,include
来源: https://www.cnblogs.com/hzy717zsy/p/16365581.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有