Skip to content

Commit 6153d4a

Browse files
committed
Graph
1 parent 49eeee5 commit 6153d4a

12 files changed

Lines changed: 740 additions & 50 deletions

File tree

Graph/BFS/Bidirectional BFS.py

Whitespace-only changes.
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
# https://maang.in/problems/Connected-Component-Size-684?resourceUrl=cs214-cp873-pl3338-rs684&returnUrl=%5B%22%2Fcourses%2FGraph-Level-1-214%3Ftab%3Dchapters%22%5D
2+
3+
"""
4+
Description
5+
You have a 2-D array of size N×M. Consider connected 0's (which share a common edge) as one single component and 1's as walls. Replace 0's with the size of the connected component but if the size of the component is one, then leave it with 0.
6+
7+
Input Format
8+
The first line contains a single integer t, the number of test cases. For each test case, the first line contains two integers
9+
N and M and then there are N lines containing N×M binary matrix.
10+
11+
Output Format
12+
For each test case, print the final matrix after replacing all the 0's accordingly.
13+
14+
Constraints
15+
(N×M) over all test cases ≤2×105
16+
17+
0≤Ai≤1
18+
19+
Sample Input 1
20+
2
21+
2 2
22+
0 1
23+
1 0
24+
6 5
25+
1 0 0 1 0
26+
0 1 0 0 0
27+
0 0 1 1 0
28+
0 1 1 0 1
29+
1 1 1 1 1
30+
0 1 0 0 0
31+
Sample Output 1
32+
0 1
33+
1 0
34+
1 7 7 1 7
35+
4 1 7 7 7
36+
4 4 1 1 7
37+
4 1 1 0 1
38+
1 1 1 1 1
39+
0 1 3 3 3
40+
"""
41+
42+
43+
import sys
44+
from collections import deque
45+
46+
input = sys.stdin.readline
47+
print = sys.stdout.write
48+
49+
direction = [(1, 0), (0, 1), (-1, 0), (0, -1)]
50+
51+
52+
def list_ints():
53+
return list(map(int, input().split()))
54+
55+
56+
def bfs(x, y, grid):
57+
vis = set()
58+
vis.add((x, y))
59+
60+
q = deque([(x, y)])
61+
size = 0
62+
63+
while q:
64+
x, y = q.popleft()
65+
size += 1
66+
67+
for dx, dy in direction:
68+
nx, ny = x + dx, y + dy
69+
70+
if 0 <= nx < len(grid) and 0 <= ny < len(grid[0]):
71+
if (nx, ny) in vis or grid[nx][ny] == "1":
72+
continue
73+
74+
vis.add((nx, ny))
75+
q.append((nx, ny))
76+
77+
return size
78+
79+
80+
def solve():
81+
t = int(input())
82+
83+
for _ in range(t):
84+
n, m = list_ints()
85+
86+
grid = []
87+
for _ in range(n):
88+
grid.append(input().strip().split())
89+
90+
ans = []
91+
92+
for i in range(n):
93+
row = []
94+
for j in range(m):
95+
if grid[i][j] == "1":
96+
row.append("1")
97+
else:
98+
size = bfs(i, j, grid)
99+
row.append("0" if size == 1 else str(size))
100+
101+
ans.append(" ".join(row))
102+
103+
print("\n".join(ans) + "\n")
104+
105+
106+
if __name__ == "__main__":
107+
solve()
108+
109+
import sys
110+
from collections import deque
111+
112+
input = sys.stdin.readline
113+
print = sys.stdout.write
114+
115+
direction = [(1, 0), (0, 1), (-1, 0), (0, -1)]
116+
117+
118+
def list_ints():
119+
return list(map(int, input().split()))
120+
121+
122+
def solve():
123+
t = int(input())
124+
125+
for _ in range(t):
126+
n, m = list_ints()
127+
128+
# for "0 1 0" input
129+
grid = [input().strip().split() for _ in range(n)]
130+
# if input is "010", use:
131+
# grid = [list(input().strip()) for _ in range(n)]
132+
133+
comp_id = [[-1] * m for _ in range(n)]
134+
comp_size = []
135+
cid = 0
136+
137+
# BFS to find components of '0'
138+
for i in range(n):
139+
for j in range(m):
140+
if grid[i][j] == "0" and comp_id[i][j] == -1:
141+
q = deque([(i, j)])
142+
comp_id[i][j] = cid
143+
size = 1
144+
145+
while q:
146+
x, y = q.popleft()
147+
148+
for dx, dy in direction:
149+
nx, ny = x + dx, y + dy
150+
151+
if 0 <= nx < n and 0 <= ny < m:
152+
if grid[nx][ny] == "0" and comp_id[nx][ny] == -1:
153+
comp_id[nx][ny] = cid
154+
q.append((nx, ny))
155+
size += 1
156+
157+
comp_size.append(size)
158+
cid += 1
159+
160+
# Build answer
161+
ans = []
162+
for i in range(n):
163+
row = []
164+
for j in range(m):
165+
if grid[i][j] == "1":
166+
row.append("1")
167+
else:
168+
size = comp_size[comp_id[i][j]]
169+
row.append("0" if size == 1 else str(size))
170+
ans.append(" ".join(row))
171+
172+
print("\n".join(ans) + "\n")
173+
174+
175+
if __name__ == "__main__":
176+
solve()
177+
178+
179+
"""
180+
Time Complexity per test case: O(N×M). Space Complexity per test case: O(N×M).
181+
"""

Graph/Bipartite/Creating Teams.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# https://maang.in/problems/Creating-Teams-193?resourceUrl=cs214-cp873-pl3339-rs193&returnUrl=%5B%22%2Fcourses%2FGraph-Level-1-214%3Ftab%3Dchapters%22%5D
2+
3+
4+
"""
5+
Description
6+
There are n students in the AlgoZenith course and m friendships between them. Your task is to divide the students into two teams in such a way that no two students in a team are friends. You can freely choose the sizes of the teams. The size of each team should be positive.
7+
8+
Input Format
9+
The first input line has two integers n and m: the number of students and friendships. The students are numbered
10+
1,2,…,n.
11+
Then, there are m lines describing friendships. Each line has two integers a and b: students a and b are friends.
12+
Every friendship is between two different students. You can assume that there is at most one friendship between any two students.
13+
14+
Output Format
15+
Print YES if it's possible to divide students in two teams, otherwise print NO.
16+
17+
Constraints
18+
1≤n≤105
19+
0≤m≤2×105
20+
1≤a,b≤n
21+
22+
Sample Input 1
23+
5 3
24+
1 2
25+
1 3
26+
4 5
27+
Sample Output 1
28+
YES
29+
Sample Input 2
30+
4 3
31+
1 2
32+
2 3
33+
1 3
34+
Sample Output 2
35+
NO
36+
"""
37+
38+
import sys
39+
from sys import stdin, stdout
40+
41+
sys.setrecursionlimit(10**7)
42+
43+
44+
def dfs(v, c, color, adj):
45+
color[v] = c
46+
for u in adj[v]:
47+
if color[u] == -1:
48+
if not dfs(u, 1 - c, color, adj):
49+
return False
50+
elif color[u] == color[v]:
51+
return False
52+
return True
53+
54+
55+
def main():
56+
data = stdin.read().split()
57+
idx = 0
58+
n = int(data[idx])
59+
idx += 1
60+
m = int(data[idx])
61+
idx += 1
62+
adj = [[] for _ in range(n + 1)]
63+
for _ in range(m):
64+
u = int(data[idx])
65+
v = int(data[idx + 1])
66+
idx += 2
67+
adj[u].append(v)
68+
adj[v].append(u)
69+
color = [-1] * (n + 1)
70+
for v in range(1, n + 1):
71+
if color[v] == -1:
72+
if not dfs(v, 0, color, adj):
73+
stdout.write("NO\n")
74+
return
75+
stdout.write("YES\n")
76+
77+
78+
if __name__ == "__main__":
79+
main()
80+
81+
82+
"""
83+
⏱️ Time Complexity
84+
O(N + M)
85+
86+
Where:
87+
88+
N = number of nodes
89+
M = number of edges
90+
Why?
91+
Each node is visited once
92+
Each edge is checked twice (undirected)
93+
💾 Space Complexity
94+
O(N + M)
95+
Breakdown:
96+
adj list → O(N + M)
97+
color array → O(N)
98+
recursion stack (DFS) / queue (BFS) → O(N) worst case
99+
"""
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
"""
2+
Description
3+
You have been given a tree with N nodes and N−1 edges. You want to colour each node, such that no two adjacent nodes (directly connected by an edge) and no two nearly-adjacent nodes (both directly connected to a common node with edges) has the same colour. Your task is to find the minimum number of colours required to accomplished this.
4+
5+
Input Format
6+
The first line of input contains N. Each of the remaining N−1 lines describes an edge in terms of the two nodes it connects.
7+
8+
Output Format
9+
Print the minimum number of colours required.
10+
11+
Constraints
12+
1≤N≤10 5
13+
14+
15+
Sample Input 1
16+
4
17+
1 2
18+
4 3
19+
2 3
20+
Sample Output 1
21+
3
22+
23+
"""
24+
25+
import sys
26+
from collections import defaultdict
27+
28+
input = sys.stdin.readline
29+
print = sys.stdout.write
30+
sys.setrecursionlimit(1 << 25)
31+
32+
MOD = 10**9 + 7
33+
INF = 10**18
34+
35+
36+
def read():
37+
return sys.stdin.buffer.read()
38+
39+
40+
def ints():
41+
return map(int, input().split())
42+
43+
44+
def list_ints():
45+
return list(map(int, input().split()))
46+
47+
48+
def write_line(value=""):
49+
sys.stdout.write(str(value) + "\n")
50+
51+
52+
def write_lines(values):
53+
sys.stdout.write("\n".join(map(str, values)))
54+
if values:
55+
sys.stdout.write("\n")
56+
57+
58+
direction = [(1, 0), (0, 1), (-1, 0), (0, -1)]
59+
60+
61+
def solve():
62+
[n] = list_ints()
63+
degree = [0] * (n + 1)
64+
for _ in range(n - 1):
65+
[u, v] = list_ints()
66+
degree[u] += 1
67+
degree[v] += 1
68+
69+
write_line(max(degree) + 1)
70+
71+
72+
if __name__ == "__main__":
73+
solve()
74+
75+
"""
76+
Time: O(N)
77+
Space: O(N)
78+
"""
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# https://maang.in/problems/Creating-Teams-193?resourceUrl=cs214-cp873-pl3339-rs193&returnUrl=%5B%22%2Fcourses%2FGraph-Level-1-214%3Ftab%3Dchapters%22%5D
2+
3+
"""
4+
Description
5+
There are n students in the AlgoZenith course and m friendships between them. Your task is to divide the students into two teams in such a way that no two students in a team are friends. You can freely choose the sizes of the teams. The size of each team should be positive.
6+
7+
Input Format
8+
The first input line has two integers n and m: the number of students and friendships. The students are numbered 1,2,…,n.
9+
Then, there are m lines describing friendships. Each line has two integers a and b: students a and b are friends.
10+
Every friendship is between two different students. You can assume that there is at most one friendship between any two students.
11+
12+
Output Format
13+
Print YES if it's possible to divide students in two teams, otherwise print NO.
14+
15+
Constraints
16+
1≤n≤105
17+
0≤m≤2×105
18+
1≤a,b≤n
19+
20+
Sample Input 1
21+
5 3
22+
1 2
23+
1 3
24+
4 5
25+
Sample Output 1
26+
YES
27+
Sample Input 2
28+
4 3
29+
1 2
30+
2 3
31+
1 3
32+
Sample Output 2
33+
NO
34+
"""

Graph/Cycle Detection/Cycle Detection.py

Whitespace-only changes.

0 commit comments

Comments
 (0)