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