藍橋杯 網路尋路 python 滿分解法

2021-10-22 14:29:07 字數 4070 閱讀 9197

方法二:遍歷中間路徑法

總結本人小白一枚,最近在準備python組的藍橋杯,在此記錄一下真題——網路尋路的滿分解法~

首先,我想到的第一種方法是回溯法。基本思路為先通過輸入通過資料結構記錄圖的結構。然後以每乙個元素為起點進行遍歷。同時在這個過程中要保證每一條邊不能重複出現,頂點只可以在開始的節點和結束的節點重複出現…,具體的思路不再描述了,因為不提倡這種方法。

o(n**4), 因為在最壞的情況下,每個頂點與其餘n-1個頂點都會有邊進行聯絡。所以我們遍歷4個節點的時候就相當於for 迴圈了4遍,即使進行剪枝,仍然改變不了複雜度為n的四次方的事實

如下:

#定義邊的類,to表示它的終點,source_edge表示它的源點的另外一條出邊

class edge:

def __init__(self,to=-1):

self.to=to

self.source_edge=-1

#方法一:回溯演算法

## 時間複雜度o(n**4),

##因為在極端的情況下,每個頂點可能與另外的n-1條邊連線。所以我們第一次遍歷n的次數,第二次,第三次,第四次都是遍歷n次數

#在dsf的過程中,第一保證每條邊只使用一次

沒有辦法,第一種的時間複雜度太高了,即使是剪枝仍然解決不了問題。所以換一種思路來看看。我們拿最後乙個例子來研究一下:

如圖所示為每個頂點的度。我們在方法一中,通過o(n)的時間可以記錄這個圖的結構,即每個節點它的度是多少,它與哪寫節點相鄰。於是我們突發奇想,如果我們遍歷中間的兩個節點試試呢?

比如,節點1和節點2。節點1的度為3,節點2的度為2,二者相交後,節點1剩下的度為3-1=2,節點2剩下的度為2-1=1.所以二者組合後的以1,2為中間兩點的組合有2*1*2種,之所以在後面又乘上了乙個2,是因為我們可以逆序。。。

就是這個思路,有沒有感覺很巧妙~

o(n**2)

#方法二,時間複雜度為o(n^2)

class edge:

def __init__(self,to=-1):

self.to=to

self.source_edge=-1

class solution:

def networkroads(self,n,m,edges) -> str:

def addedge(u,v):

nonlocal cnt

nonlocal lines_num

edge_list[cnt].to=v

edge_list[cnt].source_edge=pre[u]

lines_num[u]+=1

pre[u]=cnt

cnt+=1

def twonode(start):

nonlocal ans

p=pre[start]

while p!=-1:

q=edge_list[p].to

if q>start:

ans+=(lines_num[start]-1)*(lines_num[q]-1)

p=edge_list[p].source_edge

cnt=0

#lines_num[i]表示第i個點的邊的度

lines_num=[0 for _ in range(n+1)]

pre=[(-1) for _ in range(n+1)]

edge_list=list()

for x,y in edges:

addedge(x,y)

addedge(y,x)

ans=0

for i in range(1,n+1):

twonode(i)

return ans*2

if __name__=='__main__':

solution=solution

n,m=map(int,input().split())

edges=list()

for i in range(m):

node1,node2=map(int,input().split())

## n,m=3,3

## edges=[(1,2),(2,3),(1,3)]

## n,m=4,4

## edges=[(1,2),(2,3),(3,1),(1,4)]

## n,m=3,1

## edges=[(1,3)]

result=solution.networkroads(solution,n,m,edges)

print(result)

這道題目,解題的技巧就在於方法二。當我們乙個點乙個點的來進行遍歷時時間複雜度很高,於是我們就直接遍歷中間的路徑。對於c++之類的,用方法一可以通過,但是對於python**來說,就一定要採用花費時間最少的演算法。

藍橋杯 網路尋路

歷屆試題 網路尋路 時間限制 1.0s 記憶體限制 256.0mb 問題描述 x 國的乙個網路使用若干條線路連線若干個節點。節點間的通訊是雙向的。某重要資料報,為了安全起見,必須恰好被 兩次到達目的地。該包可能在任意乙個節點產生,我們需要知道該網路中一共有多少種不同的 路徑。源位址和目標位址可以相同...

藍橋杯 網路尋路

歷屆試題 網路尋路 時間限制 1.0s 記憶體限制 256.0mb 問題描述 x 國的乙個網路使用若干條線路連線若干個節點。節點間的通訊是雙向的。某重要資料報,為了安全起見,必須恰好被 兩次到達目的地。該包可能在任意乙個節點產生,我們需要知道該網路中一共有多少種不同的 路徑。源位址和目標位址可以相同...

藍橋杯 網路尋路

x 國的乙個網路使用若干條線路連線若干個節點。節點間的通訊是雙向的。某重要資料報,為了安全起見,必須恰好被 兩次到達目的地。該包可能在任意乙個節點產生,我們需要知道該網路中一共有多少種不同的 路徑。源位址和目標位址可以相同,但中間節點必須不同。如下圖所示的網路。1 2 3 1 是允許的 1 2 1 ...