方法二:遍歷中間路徑法
總結本人小白一枚,最近在準備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 ...