贪心构造+枚举子集+有向图判环

lc3445

无向图当中用一个数组标记每个节点是否访问过,记录这个节点它的父节点,如果一个节点不是fa &&被访问过,就说明环

可以bfs/dfs/union判环

推到有向图 两种状态表示已经无法判定,我们可以用到三色染色法

class Solution {

public:

vector<vector<int>> supersequences(vector<string>& words) {

// 收集有哪些字母,同时建图

int all = 0, mask2 = 0;

vector<int> g26{};

for (auto& s : words) {

int x = s0 - 'a', y = s1 - 'a';

all |= 1 << x | 1 << y;

if (x == y) {

mask2 |= 1 << x;

}

gx.push_back(y);

}

// 判断是否有环

auto has_cycle = \&(int sub) -> bool {

int color26{};

auto dfs = \&(this auto&& dfs, int x) -> bool {

colorx = 1;

for (int y : gx) {

// 只遍历在 sub 中的字母

if ((sub >> y & 1) == 0) {

continue;

}

if (colory == 1 || colory == 0 && dfs(y)) {

return true;

}

}

colorx = 2;

return false;

};

for (int i = 0; i < 26; i++) {

// 只遍历在 sub 中的字母

if (colori == 0 && sub >> i & 1 && dfs(i)) {

return true;

}

}

return false;

};

unordered_set<int> st;

int max_size = 0;

// 枚举 mask1 的所有子集 sub

int mask1 = all ^ mask2;

int sub = mask1;

do {

int size = popcount((unsigned) sub);

// 剪枝:如果 size < min_size 就不需要判断了

if (size >= max_size && !has_cycle(sub)) {

if (size > max_size) {

max_size = size;

st.clear();

}

st.insert(sub);

}

sub = (sub - 1) & mask1;

} while (sub != mask1);

vector<vector<int>> ans;

for (int sub : st) {

vector<int> cnt(26);

for (int i = 0; i < 26; i++) {

cnti = (all >> i & 1) + ((all ^ sub) >> i & 1);

}

ans.push_back(cnt);

}

return ans;

}

};

相关推荐
手写码匠5 分钟前
手写 GraphRAG:从零实现图增强检索增强生成系统
人工智能·深度学习·算法·aigc
BomanGe111 分钟前
NSK重载高刚性滚珠丝杠技术详解
经验分享·算法·规格说明书
Matrix_111 小时前
手机里的计算摄影:广角形变校正算法
人工智能·算法·智能手机·计算摄影
WBluuue1 小时前
数据结构与算法:有序表(二):跳表
数据结构·c++·算法·skiplist
x138702859572 小时前
c语言中srtlen(指针使用计算字符长度)、传值和传址调用
c语言·开发语言·算法·visual studio
海兰2 小时前
【实用程序】电商销售分析仪表盘 — 从零搭建一个AI参与的全栈数据洞察系统
人工智能·学习·算法
zwenqiyu3 小时前
P5283 [十二省联考 2019] 异或粽子题解
c++·学习·算法
wayz113 小时前
Momentum:TSI(真实强度指数)技术指标详解
算法·金融·数据分析·量化交易·特征工程
万事大吉CC3 小时前
Python 笔试输入模板总结
python·算法
lihao lihao4 小时前
Linux信号
开发语言·c++·算法