Skip to content

Commit ddc2d98

Browse files
committed
🥺chore
1 parent fce87cd commit ddc2d98

File tree

3 files changed

+126
-23
lines changed

3 files changed

+126
-23
lines changed

practice2/g/main.py

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,66 @@ def make_list(n, *args, default=0): return [make_list(*args, default=default) fo
3636

3737
sys.setrecursionlimit(1000000)
3838

39+
class DAG:
40+
def __init__(self, n, AB):
41+
self.n = n
42+
self.G = [[] for _ in range(n)]
43+
self.revG = [[] for _ in range(n)]
44+
self.AB = AB
45+
for a, b in AB:
46+
self.G[a].append(b)
47+
self.revG[b].append(a)
48+
49+
def scc(self):
50+
visited = [False] * self.n
51+
order = []
52+
for i in range(self.n):
53+
if visited[i]: continue
54+
55+
q = deque([i])
56+
visited[i] = True
57+
while q:
58+
v = q[-1]
59+
for u in self.G[v]:
60+
if not visited[u]:
61+
q.append(u)
62+
visited[u] = True
63+
break
64+
else:
65+
#全て訪問済みの時
66+
q.pop()
67+
order.append(v)
68+
69+
visited = [False] * self.n
70+
scc = []
71+
for i in order[::-1]:
72+
if visited[i]: continue
73+
tmp = [i]
74+
visited[i] = True
75+
q = deque([i])
76+
77+
while q:
78+
v = q.pop()
79+
for u in self.revG[v]:
80+
if visited[u]: continue
81+
visited[u] = True
82+
tmp.append(u)
83+
q.append(u)
84+
scc.append(tmp)
85+
86+
return scc
87+
88+
89+
3990
def main():
40-
N = I()
91+
N, M = LI()
92+
AB = LIR(M)
93+
g = DAG(N, AB)
94+
scc = g.scc()
95+
print(len(scc))
96+
for es in scc:
97+
print(len(es), *es)
98+
4199

42100
if __name__ == '__main__':
43101
main()

snipetts/graph.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
class DAG:
2+
def __init__(self, n, AB):
3+
self.n = n
4+
self.G = [[] for _ in range(n)]
5+
self.revG = [[] for _ in range(n)]
6+
self.AB = AB
7+
for a, b in AB:
8+
self.G[a].append(b)
9+
self.revG[b].append(a)
10+
11+
def scc(self):
12+
visited = [False] * self.n
13+
order = []
14+
for i in range(self.n):
15+
if visited[i]: continue
16+
17+
q = deque([i])
18+
visited[i] = True
19+
while q:
20+
v = q[-1]
21+
for u in self.G[v]:
22+
if not visited[u]:
23+
q.append(u)
24+
visited[u] = True
25+
break
26+
else:
27+
#全て訪問済みの時
28+
q.pop()
29+
order.append(v)
30+
31+
visited = [False] * self.n
32+
scc = []
33+
for i in order[::-1]:
34+
if visited[i]: continue
35+
tmp = [i]
36+
visited[i] = True
37+
q = deque([i])
38+
39+
while q:
40+
v = q.pop()
41+
for u in self.revG[v]:
42+
if visited[u]: continue
43+
visited[u] = True
44+
tmp.append(u)
45+
q.append(u)
46+
scc.append(tmp)
47+
48+
return scc
49+

snipetts/unionfind.py

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,25 @@
11
class UnionFind:
2-
def __init__(self, n):
3-
self._parent = [i for i in range(n)]
4-
self._rank = [0 for _ in range(n)]
5-
self._group_size = [1 for _ in range(n)]
6-
self.num_of_groups = n
2+
def __init__(self, N): self.N, self.group_count, self.root, self.rank = N, N, [-1] * N, [0] * N
3+
def __repr__(self): return str(self.all_groups())
74

85
def find(self, x):
9-
vs = []
10-
while self._parent[x] != x:
11-
vs.append(x)
12-
x = self._parent[x]
13-
for v in vs: self._parent[v] = x
6+
while self.root[x] >= 0: x = self.root[x]
147
return x
158

169
def union(self, x, y):
17-
px, py = self.find(x), self.find(y)
18-
if px == py: return
19-
if self._rank[px] < self._rank[py]:
20-
self._parent[px] = py
21-
self._group_size[py] += self._group_size[px]
22-
else:
23-
self._parent[py] = px
24-
self._group_size[px] += self._group_size[py]
25-
if self._rank[px] == self._rank[py]: self._rank[py] += 1
26-
self.num_of_groups -= 1
10+
x, y = self.find(x), self.find(y)
11+
if x == y: return
12+
if self.rank[x] > self.rank[y]: x, y = y, x
13+
self.root[y] += self.root[x]
14+
self.root[x] = y
15+
if self.rank[x] == self.rank[y]: self.rank[y] += 1
16+
self.group_count -= 1
2717

28-
def is_same(self, x, y): return self.find(x) == self.find(y)
29-
def group_size(self, x): return self._group_size[self.find(x)]
18+
def same(self, x, y): return self.find(x) == self.find(y)
19+
def count(self, x): return -self.root[self.find(x)]
20+
def members(self, x): return [i for i in range(self.N) if self.same(x, i)]
21+
def roots(self): return [i for i, x in enumerate(self.root) if x < 0]
22+
def all_groups(self):
23+
d = defaultdict(lambda: [])
24+
for i in range(self.N): d[self.find(i)].append(i)
25+
return dict(d)

0 commit comments

Comments
 (0)