ICode9

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

CF #816 D - 2+ doors

2022-08-29 17:33:40  阅读:215  来源: 互联网

标签:int 30 CF add continue doors include fl 816


建图,贪心

Problem - D - Codeforces

题意

给 q 个约束 \(a[i] \;|\;a[j]==x\), 求满足这 q 个约束的最小字典序的数组 a (保证有解)

思路

  1. 把 q 个约束中 i == j 的优先处理掉,即 a[i] = x,这些位置不再考虑

  2. 按位考虑,分别处理 30 位

  3. 对于第 k 位,把 \(a[i] \;|\;a[j]==x\) 中 x 在第 k 位为 0 的先处理掉,因为此时 a[i], a[j] 的第 k 位只能为 0;

    其他的位置都赋 1,这样就足够满足所有约束了

  4. 接下来要找到字典序最小的,就贪心地让下标从小到大尝试,看是否能让 a[i] 的第 k 位为 0

  5. 可以把约束中的两个下标连边,表示一条边中至少有个点为 1,然后从小到达枚举 u,再枚举 u 的邻点 v,如果所有的 v 此时都为 1,那么 u 就可以为 0;否则 u 只能为 1

  6. 注意这样会建 30 个图,实际上建一个图就好,用 w >> k & 1 取出第 k 位时的边

#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 = 1e5 + 10;
int n, q;

struct Edge
{
	int v, w;
};
vector<vector<Edge> > G(N);
int a[N];
bool st[N];
void add(int u, int v, int w)
{
	G[u].push_back({v, w});
}
int main()
{
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	cin >> n >> q;
	for (int i = 1; i <= n; i++)
		a[i] = (1 << 30) - 1;
	while(q--)
	{
		int u, v, w;
		cin >> u >> v >> w;
		if (u == v)
		{
			a[u] = w;
			st[u] = true;
			continue;
		}
		add(u, v, w), add(v, u, w);
		for (int k = 0; k < 30; k++)
		{
			if (!(w >> k & 1))
			{
				if (a[u] >> k & 1)
					a[u] ^= (1 << k);
				if (a[v] >> k & 1)
					a[v] ^= (1 << k);
			}
		}
	}
	for (int k = 0; k < 30; k++)
	{
		for (int u = 1; u <= n; u++)
		{
			if (st[u] || !(a[u] >> k & 1))
				continue;
			bool fl = true;
			for (auto [v, w] : G[u])
			{
				if (!(w >> k & 1))
					continue;
				if (!(a[v] >> k & 1))
				{
					fl = false;
					break;
				}
			}
			if (fl)
				a[u] ^= (1 << k);
		}
	}
	for (int i = 1; i <= n; i++)
		cout << a[i] << " ";
	cout << endl;
    return 0;
}

标签:int,30,CF,add,continue,doors,include,fl,816
来源: https://www.cnblogs.com/hzy717zsy/p/16636643.html

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

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

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

ICode9版权所有