Skip to content

Commit 966eae6

Browse files
committed
Added C++ solution for 3400-3499/3435. Frequencies of Shortest Supersequences
1 parent 4486047 commit 966eae6

File tree

1 file changed

+248
-0
lines changed
  • solution/3400-3499/3435.Frequencies of Shortest Supersequences

1 file changed

+248
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
#include <vector>
2+
#include <string>
3+
#include <queue>
4+
#include <stack>
5+
#include <set>
6+
#include <functional>
7+
using namespace std;
8+
9+
class Solution
10+
{
11+
public:
12+
vector<vector<int>> supersequences(vector<string> &words)
13+
{
14+
const int ALPHA = 26;
15+
bool used[ALPHA] = {};
16+
for (auto &w : words)
17+
for (char c : w)
18+
used[c - 'a'] = true;
19+
20+
vector<int> charMap(ALPHA, -1);
21+
vector<char> chars;
22+
int charCount = 0;
23+
for (int c = 0; c < ALPHA; c++)
24+
{
25+
if (used[c])
26+
{
27+
charMap[c] = charCount++;
28+
chars.push_back('a' + c);
29+
}
30+
}
31+
32+
vector<vector<bool>> graph(charCount, vector<bool>(charCount));
33+
vector<bool> selfLoop(charCount);
34+
for (auto &w : words)
35+
{
36+
int u = charMap[w[0] - 'a'], v = charMap[w[1] - 'a'];
37+
if (u == v)
38+
selfLoop[u] = true;
39+
else
40+
graph[u][v] = true;
41+
}
42+
43+
vector<int> disc(charCount, -1), low(charCount), comp(charCount, -1);
44+
vector<bool> inStack(charCount);
45+
stack<int> stk;
46+
int time = 0, sccTotal = 0;
47+
48+
function<void(int)> tarjan = [&](int u)
49+
{
50+
disc[u] = low[u] = time++;
51+
stk.push(u);
52+
inStack[u] = true;
53+
54+
for (int v = 0; v < charCount; v++)
55+
{
56+
if (!graph[u][v])
57+
continue;
58+
if (disc[v] == -1)
59+
{
60+
tarjan(v);
61+
low[u] = min(low[u], low[v]);
62+
}
63+
else if (inStack[v])
64+
{
65+
low[u] = min(low[u], disc[v]);
66+
}
67+
}
68+
69+
if (low[u] == disc[u])
70+
{
71+
while (true)
72+
{
73+
int v = stk.top();
74+
stk.pop();
75+
inStack[v] = false;
76+
comp[v] = sccTotal;
77+
if (v == u)
78+
break;
79+
}
80+
sccTotal++;
81+
}
82+
};
83+
84+
for (int i = 0; i < charCount; i++)
85+
if (disc[i] == -1)
86+
tarjan(i);
87+
88+
vector<vector<int>> sccGroups(sccTotal);
89+
for (int i = 0; i < charCount; i++)
90+
sccGroups[comp[i]].push_back(i);
91+
92+
vector<vector<int>> sccGraph(sccTotal);
93+
vector<int> inDegree(sccTotal);
94+
for (int u = 0; u < charCount; u++)
95+
{
96+
for (int v = 0; v < charCount; v++)
97+
{
98+
if (graph[u][v] && comp[u] != comp[v])
99+
{
100+
sccGraph[comp[u]].push_back(comp[v]);
101+
inDegree[comp[v]]++;
102+
}
103+
}
104+
}
105+
106+
queue<int> q;
107+
vector<int> topoOrder;
108+
for (int i = 0; i < sccTotal; i++)
109+
if (inDegree[i] == 0)
110+
q.push(i);
111+
112+
while (!q.empty())
113+
{
114+
int u = q.front();
115+
q.pop();
116+
topoOrder.push_back(u);
117+
for (int v : sccGraph[u])
118+
{
119+
if (--inDegree[v] == 0)
120+
q.push(v);
121+
}
122+
}
123+
124+
auto isAcyclic = [](const vector<vector<bool>> &g, int mask, int n)
125+
{
126+
vector<bool> removed(n);
127+
for (int i = 0; i < n; i++)
128+
if (mask & (1 << i))
129+
removed[i] = true;
130+
131+
vector<int> deg(n);
132+
for (int u = 0; u < n; u++)
133+
{
134+
if (removed[u])
135+
continue;
136+
for (int v = 0; v < n; v++)
137+
{
138+
if (!removed[v] && g[u][v])
139+
deg[v]++;
140+
}
141+
}
142+
143+
queue<int> q;
144+
int cnt = 0;
145+
int total = n - __builtin_popcount(mask);
146+
for (int i = 0; i < n; i++)
147+
if (!removed[i] && deg[i] == 0)
148+
q.push(i);
149+
150+
while (!q.empty())
151+
{
152+
int u = q.front();
153+
q.pop();
154+
cnt++;
155+
for (int v = 0; v < n; v++)
156+
{
157+
if (!removed[v] && g[u][v] && --deg[v] == 0)
158+
q.push(v);
159+
}
160+
}
161+
return cnt == total;
162+
};
163+
164+
auto findMinFVS = [&](const vector<vector<bool>> &g, int n)
165+
{
166+
set<vector<int>> patterns;
167+
for (int sz = 0; sz <= n; sz++)
168+
{
169+
bool found = false;
170+
for (int mask = 0; mask < (1 << n); mask++)
171+
{
172+
if (__builtin_popcount(mask) != sz)
173+
continue;
174+
if (isAcyclic(g, mask, n))
175+
{
176+
vector<int> freq(n, 1);
177+
for (int i = 0; i < n; i++)
178+
if (mask & (1 << i))
179+
freq[i] = 2;
180+
patterns.insert(freq);
181+
found = true;
182+
}
183+
}
184+
if (found)
185+
break;
186+
}
187+
return vector<vector<int>>(patterns.begin(), patterns.end());
188+
};
189+
190+
vector<vector<vector<int>>> sccPatterns(sccTotal);
191+
for (int i = 0; i < sccTotal; i++)
192+
{
193+
auto &group = sccGroups[i];
194+
if (group.size() == 1)
195+
{
196+
sccPatterns[i] = selfLoop[group[0]] ? vector<vector<int>>{{2}} : vector<vector<int>>{{1}};
197+
continue;
198+
}
199+
200+
vector<vector<bool>> subgraph(group.size(), vector<bool>(group.size()));
201+
vector<int> localToGlobal(group.size());
202+
for (int j = 0; j < group.size(); j++)
203+
{
204+
localToGlobal[j] = group[j];
205+
if (selfLoop[group[j]])
206+
subgraph[j][j] = true;
207+
for (int k = 0; k < group.size(); k++)
208+
{
209+
if (graph[group[j]][group[k]])
210+
subgraph[j][k] = true;
211+
}
212+
}
213+
sccPatterns[i] = findMinFVS(subgraph, group.size());
214+
}
215+
216+
vector<vector<int>> result = {{}};
217+
for (int scc : topoOrder)
218+
{
219+
vector<vector<int>> newResult;
220+
for (auto &freq : result)
221+
{
222+
for (auto &pattern : sccPatterns[scc])
223+
{
224+
vector<int> newFreq = freq;
225+
newFreq.resize(charCount);
226+
for (int i = 0; i < sccGroups[scc].size(); i++)
227+
{
228+
int globalIdx = sccGroups[scc][i];
229+
newFreq[globalIdx] = pattern[i];
230+
}
231+
newResult.push_back(newFreq);
232+
}
233+
}
234+
result = move(newResult);
235+
}
236+
237+
set<vector<int>> uniqueFreqs;
238+
for (auto &freq : result)
239+
{
240+
vector<int> finalFreq(ALPHA);
241+
for (int i = 0; i < charCount; i++)
242+
finalFreq[chars[i] - 'a'] = freq[i];
243+
uniqueFreqs.insert(finalFreq);
244+
}
245+
246+
return vector<vector<int>>(uniqueFreqs.begin(), uniqueFreqs.end());
247+
}
248+
};

0 commit comments

Comments
 (0)