Cho một đồ thị luồng điều khiển (CFG) gồm n khối cơ bản và m cạnh có hướng — CFG có thể chứa chu trình (vòng lặp). Mỗi khối gồm một dãy lệnh tuần tự, mỗi lệnh có một trong hai dạng x = y op z (op ∈{+,−,∗,/}, không hiệu ứng phụ) hoặc PRINT y (LUÔN được giữ lại vì có hiệu ứng phụ, không bao giờ là mã chết). Khối nào không có cạnh ra (out-degree 0) được coi là khối thoát (exit) của chương trình, có LiveOut=∅ (không biến nào cần dùng sau khi chương trình kết thúc).
Áp dụng thuật toán phân tích biến sống (live variable analysis) chuẩn, lặp tới điểm cố định (cần thiết vì CFG có thể có chu trình):
LiveOut[b]=⋃s laˋ khoˆˊi keˆˊ tieˆˊp của bLiveIn[s](hoặc ∅ neˆˊu b khoˆng coˊ khoˆˊi keˆˊ tieˆˊp)
LiveIn[b] được tính bằng cách quét NGƯỢC các câu lệnh trong khối b, xuất phát từ live=LiveOut[b]: gặp PRINT y thì giữ và thêm y vào live; gặp x = y op z thì nếu x∈live giữ lại lệnh (SỐNG), cập nhật live←(live∖{x})∪{caˊc toaˊn hạng laˋ bieˆˊn trong y,z}; nếu x∈/live, lệnh CHẾT và live giữ nguyên.
Tại điểm cố định (khi LiveIn, LiveOut mọi khối không đổi qua một vòng lặp toàn bộ các khối), hãy đếm TỔNG số câu lệnh x = y op z trên TOÀN BỘ CFG được xác định là CHẾT (không tính các lệnh PRINT).
Dòng 1: hai số nguyên n, m (1≤n≤100, 0≤m≤300). m dòng tiếp theo, mỗi dòng "p q" là cạnh có hướng p→q. Sau đó lần lượt n khối, khối thứ i gồm: một dòng số nguyên ki (số câu lệnh trong khối, có thể 0), rồi ki dòng câu lệnh dạng x = y op z hoặc PRINT y.
In ra đúng một số nguyên duy nhất — tổng số câu lệnh gán bị xác định là mã chết trên toàn CFG.
Ví dụ:
Đầu vào:
1 0
3
x = a + b
y = a * b
w = x + 1
Đầu ra:
3
Đầu vào:
4 4
1 2
2 3
3 2
2 4
3
a = 1 + 0
b = 2 + 0
d = 5 + 5
0
2
c = a + b
a = c + 1
1
PRINT a
Đầu ra:
1
Đang tải editor...