CCF-201509-4-高速公路

这题很明显是要找强连通分量,找到图中所有的强连通分量,并计算每个分量的城市对数相加得出答案。计算城市对的方法为:强连通分量的结点数 * (强连通分量的结点-1)/ 2

python代码:

import sys

sys.setrecursionlimit(10 ** 7)


def tarjan(u):
    global idx
    global bcnt
    idx += 1
    dfn[u] = low[u] = idx
    stack.append(u)
    in_stack[u] = True

    for v in graph[u]:
        if not dfn[v]:
            tarjan(v)  # dfs(v)
            low[u] = min(low[u], low[v])  # 回溯
        elif in_stack[v]:
            low[u] = min(low[u], dfn[v])

    # 回溯后,判断dfn[u] == low[u],把u以上的点弹出
    if dfn[u] == low[u]:
        sccs[bcnt] = []
        while True:
            v = stack.pop()
            in_stack[v] = False
            sccs[bcnt].append(v)
            if u == v:
                break
        bcnt += 1


n, m = map(int, input().split())
graph = [[] for _ in range(n)]
for i in range(m):
    from_n, to_n = [int(e) - 1 for e in input().split()]
    graph[from_n].append(to_n)

# 结点的时间戳,顺便充当标记数组,0代表未被访问,大于0表示访问过
dfn = [0] * n

# 结点的最小时间
low = [0] * n

# 当前时间
idx = 0

stack = []

# 标记是否在栈中
in_stack = [False] * n

# 强连通分量集
sccs = {}

# 强连通分量数量
bcnt = 0

for i in range(n):
    if not dfn[i]:
        tarjan(i)

ans = 0
for v in sccs.values():
    cnt = len(v)
    ans += int(cnt / 2 * (cnt - 1))
print(ans)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值