本文共 3434 字,大约阅读时间需要 11 分钟。
为了解决这个问题,我们需要找到图的最大半连通子图的节点数K,以及子图的数量C mod X。最大半连通子图等价于求一个强连通分量构成的最长链。以下是解决方案的详细步骤:
import sysfrom collections import defaultdictdef main(): sys.setrecursionlimit(1 << 25) n, m, mod = map(int, sys.stdin.readline().split()) h = [-1] * (n + 1) hs = [-1] * (n + 1) e = [0] * (2 * m + 2) ne = [0] * (2 * m + 2) idx = 0 for _ in range(m): a, b = map(int, sys.stdin.readline().split()) if h[a] == -1: h[a] = idx hs[a] = idx ne[idx] = b e[idx] = h[b] idx += 1 if h[b] == -1: h[b] = idx hs[b] = idx ne[idx] = a e[idx] = h[a] idx += 1 id = [0] * (n + 1) Size = [0] * (n + 1) scc_cnt = 0 timestamp = [0] * (n + 1) dfn = [0] * (n + 1) low = [0] * (n + 1) in_stk = [False] * (n + 1) stk = [] top = 0 def tarjan(u): nonlocal timestamp dfn[u] = low[u] = timestamp[0] timestamp[0] += 1 stk.append(u) in_stk[u] = True for i in range(h[u], -1, -1): v = ne[i] if dfn[v] == 0: tarjan(v) low[u] = min(low[u], low[v]) elif in_stk[v]: low[u] = min(low[u], dfn[v]) if dfn[u] == low[u]: scc_cnt += 1 y = stk.pop() in_stk[y] = False id[y] = scc_cnt Size[scc_cnt] = Size[id[y]] + 1 for v in stk: in_stk[v] = False id[v] = scc_cnt Size[scc_cnt] += 1 while stk and dfn[stk[-1]] != low[stk[-1]]: pass for u in range(1, n + 1): if dfn[u] == 0: tarjan(u) scc = defaultdict(list) for u in range(1, n + 1): for i in range(h[u], -1, -1): v = ne[i] if id[u] != id[v]: scc[id[u]].append(id[v]) edges = defaultdict(set) for u in scc: for v in scc[u]: if v not in edges[u]: edges[u].add(v) in_degree = defaultdict(int) for u in edges: for v in edges[u]: in_degree[v] += 1 topo_order = [] queue = [] for u in scc: if in_degree.get(u, 0) == 0: queue.append(u) while queue: u = queue.pop(0) topo_order.append(u) for v in edges[u]: in_degree[v] -= 1 if in_degree[v] == 0: queue.append(v) dp = defaultdict(int) g = defaultdict(int) max_f = 0 for u in topo_order: if dp[u] > 0: for v in edges[u]: if dp[v] < dp[u] + Size[u]: dp[v] = dp[u] + Size[u] g[v] = (g[u] * g[v]) % mod elif dp[v] == dp[u] + Size[u]: g[v] = (g[u] + g[v]) % mod if dp[u] > max_f: max_f = dp[u] K = max_f C = 0 for u in topo_order: if dp[u] == max_f: C = (C + g[u]) % mod print(K) print(C % mod)if __name__ == "__main__": main()
该方法高效地处理了大规模图数据,确保在合理时间内完成任务。
转载地址:http://baor.baihongyu.com/