📜  门| Gate IT 2007 |问题28(1)

📅  最后修改于: 2023-12-03 15:12:39.151000             🧑  作者: Mango

门| Gate IT 2007 |问题28

问题描述

在一个无向图中,每一条边都被彩色为红色、绿色、蓝色三种颜色之一。现在从这个无向图中去掉一个点和与该点相连的所有边,得到一个新的无向图。你需要找到一个点,使得去掉该点和相连的所有边后得到的新图中,与该点相连的三种颜色的边数量之和最小。

输入格式

第一行输入一个整数 $n$,表示无向图的节点个数。节点从 $1$ 到 $n$ 标号。

接下来 $n$ 行每行 $n$ 个数字,第 $i$ 行第 $j$ 个表示第 $i$ 个节点到第 $j$ 个节点之间的边的颜色,其中 $0$ 表示无边,$1$ 表示红色边,$2$ 表示绿色边,$3$ 表示蓝色边。

输出格式

输出一个整数,表示最小的相连三种颜色的边数量之和。

题解

对于每一个点 $i$,记将 $i$ 及相连的所有边删除后的图为 $G_i$。

对于每种颜色的边,我们可以预处理出一个表 $c$,其中 $c_{i,j}$ 表示在整个图中这种颜色的边的数量,$c_{i,j,0}$、$c_{i,j,1}$、$c_{i,j,2}$ 分别表示这种颜色的边在 $G_i$ 中的数量。

我们需要保证 $i$ 被删除后,其与相连的所有边都被删除。因此,我们需要计算从 $i$ 到 $j$ 的边是否被删除。

事实上,根据我们对问题的定义,$i$ 和 $j$ 的边只有在 $i$ 或 $j$ 中的另一个颜色与之匹配时才会被删除。因此,我们可以枚举 $i$ 和 $j$ 的颜色,并计算 $c_{i,j}$ 减掉 $c_{i,j,0}$、$c_{i,j,1}$、$c_{i,j,2}$ 中较小的那个值即可得到 $G_i$ 中这种颜色的边的数量。

最终,我们可以遍历所有点,对于每个点,计算它和其相连的所有边的三种颜色的数量和,并取三者的最小值,求得最终答案。

代码实现
def solve(n, a):
    c = [[[0] * 3 for _ in range(n)] for _ in range(n)]
    for i in range(n):
        for j in range(i + 1, n):
            if a[i][j] == 0:
                continue
            c[i][j][a[i][j] - 1] += 1
            c[j][i][a[i][j] - 1] += 1

    ans = float('inf')
    for i in range(n):
        cnt = [0, 0, 0]
        for j in range(n):
            if i == j:
                continue
            for k in range(3):
                cnt[k] += c[i][j][k] if c[i][j][k] < c[i][j][0] + c[i][j][1] + c[i][j][2] - c[i][j][k] else 0
        ans = min(ans, sum(cnt))
    return ans

该函数的时间复杂度为 $O(n^3)$。