AtCoder Context ABC 075 C Bridge(橋)---DFS,BFS解法

運行要求
運行時間限制: 2sec
內存限制: 1024MB
原文連接node

題目
有一個樹狀圖由N個頂點和M條邊組成。這個樹狀圖的M條邊裏,不含有2重邊自我循環邊
第i(1<=i<=M)條邊,鏈接着頂點ai和bi。
若有有一條邊,去掉它,整個樹狀圖就不能鏈接起來的話,這條邊就稱爲橋。
求M條邊中,橋的數量。微信

注:app

  • 自我循環的邊:編號爲i的邊,ai=bi(1<=i<=M)
  • N-1 <= M <= min(N(N-1)/2 , 50)
  • 1<=ai < bi <= N
  • 給出的樹狀圖,不包含2重邊和自我循環邊
  • 給出的樹狀圖是鏈接起來的

輸入
輸入都以如下標準從命令行輸入spa

N M
a1 b1
a2 b2
a3 b3
.
.
aM bM

輸出
M條邊中,橋的個數命令行

例1
輸入code

7 7
1 3
2 7
3 4
4 5
4 6
5 6
6 7

輸出blog

4

給出的樹形圖以下圖所示內存

570677a9809fd7a5b63bff11e5d9bf79.png

圖中,紅色的邊爲橋,總共有4條rem

例2
輸入get

3 3
1 2
1 3
2 3

輸出

0

橋不存在的狀況也有

例3
輸入

6 5
1 2
2 3
3 4
4 5
5 6

輸出

5

全部的邊都是橋的狀況也存在

讀懂題目

給出了N個點
給除了M條邊
這M條邊鏈接了N個點

不含有2重邊(M條邊裏沒有重複的邊)
不含有自我循環邊。(M條邊裏每條邊都是鏈接兩個不一樣的點)

解題思路

樹狀圖的題目,直覺上能夠用深度遍歷(DFS)和廣度遍歷(BFS)來解決。可是遍歷咱們可以作到的就是遍歷,如何和題目要求的橋的數量鏈接起來呢?

咱們來看橋的定義(若是沒有橋,樹狀圖不能鏈接起來)
也就是說,若是有一條邊Mi,有Mi這條邊的話樹狀圖能夠鏈接,沒有Mi這條邊的話,樹狀圖就不能鏈接。
DFS和BFS裏,有一個節點狀態的概念。

如圖所示,
灰色表明節點尚未被遍歷到。
藍色表明節點已經被遍歷到了。

開始遍歷前,全部的節點的狀態都是灰色。
遍歷後,被遍歷過的節點的狀態是藍色。

名稱未設定2.001.jpeg
若是一個樹狀圖裏面的節點是相互鏈接的話,那麼選取任意一個點開始遍歷,全部的點都會被遍歷到,全部的點的狀態都會是藍色

名稱未設定2.002.jpeg
如圖所示,咱們拆掉一個不是橋的邊(4-6),從1開始遍歷,最後全部的點仍是被遍歷到

名稱未設定2.003.jpeg

如圖所示,咱們拆掉一個橋的邊(3-4),從1開始遍歷,最後不是全部的點都被遍歷到

因此,咱們能夠遍歷M條邊,沒拆一條邊,看看最後全部的點是否被遍歷到。若是沒有所有被遍歷到,那麼這條邊爲橋

遍歷的方法,有DFS和BFS。這裏咱們給出兩種解法

代碼
DFS

S = input().split(" ")
N = int(S[0])
M = int(S[1])
ARR = []
for i in range(M):
    ARR.append([int(s) for s in input().split(" ")])



def prepare(n, m, arr):
    nodes = [[] for i in range(n)]
    nodeStates = [0 for i in range(n)]
    for i in range(m):
        nodeFrom = arr[i][0] - 1
        nodeTo = arr[i][1] - 1
        nodes[nodeFrom].append(nodeTo)
        nodes[nodeTo].append(nodeFrom)

    return nodes, nodeStates


nodes, nodeStates = prepare(N, M, ARR)


def dfs(currentNodeIndex, arr, nodeStates):
    if nodeStates[currentNodeIndex] == 0:
        nodeStates[currentNodeIndex] = 1

    childNodes = arr[currentNodeIndex]
    for childNodeIndex in childNodes:
        if nodeStates[childNodeIndex] == 0:
            dfs(childNodeIndex, arr, nodeStates)

    return nodeStates


# dfs(0, nodes)


def calculate(n, m, arr):
    arr = list(arr)
    result = 0
    for ar in arr:
        brr = arr.copy()
        brr.remove(ar)
        nodes, nodeStates = prepare(n, m-1, brr)
        nodeStatesResult = dfs(0,nodes,nodeStates)
        if sum(nodeStatesResult) != n:
            result = result + 1
    print(result)


calculate(N,M,ARR)

BFS

from collections import deque

S = input().split(" ")
N = int(S[0])
M = int(S[1])
ARR = []

for i in range(M):
    ARR.append([int(s) for s in input().split(" ")])

def prepare(n, m, arr):
    nodes = [[] for i in range(n)]
    nodeStates = [0 for i in range(n)]

    for ar in arr:
        nodeFrom = ar[0] - 1
        nodeTo = ar[1] - 1
        nodes[nodeFrom].append(nodeTo)
        nodes[nodeTo].append(nodeFrom)

    return nodes, nodeStates


def bfs(startNodeIndex, arr, nodeStates):
    q = deque()

    q.append(startNodeIndex)
    nodeStates[startNodeIndex] = 1

    while q.__len__() > 0:
        nodeIndex = q.popleft()
        childNodes = arr[nodeIndex]
        for childNodeIndex in childNodes:
            if nodeStates[childNodeIndex] == 0:
                q.append(childNodeIndex)
                nodeStates[childNodeIndex] = 1

    return nodeStates


def calculate(n, m, arr):
    arr = list(arr)

    result = 0

    for ar in arr:
        brr = arr.copy()
        brr.remove(ar)

        nodes, nodeStates = prepare(n, m-1, brr)
        nodeStates = bfs(0, nodes, nodeStates)

        if sum(nodeStates) != n:
            result = result + 1

    print(result)



calculate(N, M, ARR)

總結

這一題是基於遍歷的求解,能夠練習DFS和BFS

※ 另外,我會在個人微信我的訂閱號上推出一些文章,歡迎關注
二維碼.jpg

相關文章
相關標籤/搜索