Skip to content

Commit 0ebd588

Browse files
committed
928
1 parent 138f5f5 commit 0ebd588

File tree

6 files changed

+205
-0
lines changed

6 files changed

+205
-0
lines changed

leetcode/928/0.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[[1,1,0],[1,1,1],[0,1,1]]
2+
[0,1]

leetcode/928/15.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[[1,1,1,0],[1,1,0,0],[1,0,1,0],[0,0,0,1]]
2+
[3,2]

leetcode/928/30.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[[1,1,0,0],[1,1,0,1],[0,0,1,0],[0,1,0,1]]
2+
[3,0]

leetcode/928/45.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[[1,0,0,0,0,0,0,0,0],[0,1,0,0,0,0,0,0,1],[0,0,1,0,0,0,0,0,0],[0,0,0,1,0,0,0,0,1],[0,0,0,0,1,0,1,1,1],[0,0,0,0,0,1,0,0,1],[0,0,0,0,1,0,1,1,0],[0,0,0,0,1,0,1,1,0],[0,1,0,1,1,1,0,0,1]]
2+
[8,4,2,0]

leetcode/928/main.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
3+
*/
4+
5+
#include <bits/stdc++.h>
6+
7+
#include "../../lib/LeetCodeInputTemplate.hpp"
8+
#include "solution.cpp"
9+
using namespace std;
10+
11+
typedef vector<int> vi;
12+
typedef vector<vector<int>> vvi;
13+
14+
int main() {
15+
LeetCodeInput li("45.in");
16+
17+
int i = 0;
18+
auto l0 = li.get<vvi>(i++);
19+
auto l1 = li.get<vi>(i++);
20+
21+
chrono::steady_clock::time_point begin = chrono::steady_clock::now();
22+
Solution solution;
23+
auto output = solution.minMalwareSpread(l0, l1);
24+
chrono::steady_clock::time_point end = chrono::steady_clock::now();
25+
cout << "Time difference = "
26+
<< chrono::duration_cast<chrono::microseconds>(end - begin).count()
27+
<< "µs" << endl;
28+
29+
cout << output << endl;
30+
31+
// for (int i: output){
32+
// cout << i << ' ';
33+
// }
34+
35+
// for (auto i: output){
36+
// for (int j: i){
37+
// cout << j << ' ';
38+
// }
39+
// cout << '\n';
40+
// }
41+
42+
return 0;
43+
}

leetcode/928/solution.cpp

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
/*
2+
3+
time: O(n2)
4+
space: O(n)
5+
6+
Runtime
7+
229 ms
8+
Beats
9+
71.21%
10+
Memory
11+
41.8 MB
12+
Beats
13+
93.94%
14+
*/
15+
16+
#include <bits/stdc++.h>
17+
18+
using namespace std;
19+
20+
#define all(x) begin(x), end(x)
21+
typedef vector<int> vi;
22+
typedef vector<vector<int>> vvi;
23+
24+
class Solution {
25+
private:
26+
int* parent;
27+
int* union_size;
28+
29+
int get_set(int x) {
30+
if (x == parent[x]) return x;
31+
return parent[x] = get_set(parent[x]);
32+
}
33+
34+
void union_set(int a, int b) {
35+
a = get_set(a);
36+
b = get_set(b);
37+
if (a != b) {
38+
if (union_size[a] < union_size[b]) {
39+
swap(a, b);
40+
}
41+
parent[b] = a;
42+
union_size[a] += union_size[b];
43+
}
44+
}
45+
46+
public:
47+
int minMalwareSpread(vector<vector<int>>& graph, vector<int>& initial) {
48+
uint n = size(graph);
49+
uint m = size(initial);
50+
51+
int _parent[n];
52+
int _union_size[n];
53+
parent = _parent;
54+
union_size = _union_size;
55+
56+
iota(parent, parent + n, 0);
57+
fill(union_size, union_size + n, 1);
58+
59+
for (int i = 0; i < n; ++i) {
60+
for (int j = i + 1; j < n; ++j) {
61+
if (graph[i][j]) {
62+
union_set(i, j);
63+
}
64+
}
65+
}
66+
67+
/// get_set all
68+
for (int i = 0; i < n; ++i) {
69+
parent[i] = get_set(i);
70+
}
71+
72+
/// remember final union set
73+
int parent_all[n];
74+
int union_size_all[n];
75+
copy(parent, parent + n, parent_all);
76+
copy(union_size, union_size + n, union_size_all);
77+
78+
/// per iter memory to record to_reunion node by removing a node
79+
int to_reunion[n];
80+
uint to_reunion_size = 0;
81+
82+
/// per iter memory to record seen sid
83+
int seen_sid[n];
84+
memset(seen_sid, 0, sizeof(int) * n);
85+
86+
int min_infected_count = INT_MAX;
87+
int res = INT_MAX;
88+
89+
for (int i = 0; i < m; ++i) {
90+
/// del initial[i]
91+
int to_reunion_sid = get_set(initial[i]);
92+
/// get and reset all to_reunion nodes
93+
for (int j = 0; j < n; ++j) {
94+
if (get_set(j) == to_reunion_sid && j != initial[i]) {
95+
parent[j] = j;
96+
union_size[j] = 1;
97+
to_reunion[to_reunion_size++] = j;
98+
}
99+
}
100+
101+
/// reunion nodes
102+
for (int x = 0; x < to_reunion_size; ++x) {
103+
int p = to_reunion[x];
104+
for (int q = 0; q < n; ++q) {
105+
if (q != initial[i]) {
106+
if (graph[p][q]) {
107+
union_set(p, q);
108+
}
109+
}
110+
}
111+
}
112+
113+
int infected_count = 0;
114+
/// calculate total infected
115+
for (int j = 0; j < m; ++j) {
116+
if (j == i) {
117+
continue;
118+
}
119+
int sid = get_set(initial[j]);
120+
if (seen_sid[sid]) {
121+
continue;
122+
} else {
123+
infected_count += union_size[sid];
124+
seen_sid[sid] = 1;
125+
}
126+
}
127+
128+
/// record result
129+
if (infected_count < min_infected_count) {
130+
min_infected_count = infected_count;
131+
res = initial[i];
132+
} else if (infected_count == min_infected_count) {
133+
res = min(res, initial[i]);
134+
}
135+
136+
/// clear to_reunion
137+
to_reunion_size = 0;
138+
/// reset union set
139+
copy(parent_all, parent_all + n, parent);
140+
copy(union_size_all, union_size_all + n, union_size);
141+
/// clear seen_sid
142+
memset(seen_sid, 0, sizeof(int) * n);
143+
}
144+
145+
return res;
146+
}
147+
};
148+
149+
const static auto initialize = [] {
150+
std::ios::sync_with_stdio(false);
151+
std::cin.tie(nullptr);
152+
std::cout.tie(nullptr);
153+
return nullptr;
154+
}();

0 commit comments

Comments
 (0)