python 使用 最大生成樹 解決 營救問題

2021-10-10 23:01:19 字數 4000 閱讀 4440

你是紅軍指揮官,在一場軍事演習中,你的部分軍隊被藍軍包圍了。藍軍包圍的方式如下

在上圖中,每個頂點表示藍軍的部隊,頂點中數字表示藍軍在此處的人數(千人),兩點間的邊表示藍軍兩個部隊間形成的火線,火線構成的圈即是一道包圍,一條火線的戰鬥力為其相連兩個部隊的人數和,也是你要進攻這條火線所要消耗的兵力。你可以同時進攻藍軍的多條火線,請以成本最低的方式打破藍軍包圍,營救被包圍的部隊,計算出所需要消耗的兵力數(千人)

每個測試例輸出一行,是乙個正整數:打破包圍營救戰友的最小消耗兵力。

使用並查集優化的kruskal演算法實現

#!/usr/bin/env python3

#rescue.py

#fumiama 20201115

class

unionfindset

(object):

def__init__

(self, nodes)

: self.fathermap =

self.setnummap =

for node in nodes:

self.fathermap[node]

= node

self.setnummap[node]=1

deffindfather

(self, node)

: father = self.fathermap[node]

if(node != father)

: father = self.findfather(father)

self.fathermap[node]

= father

return father

defissameset

(self, a, b)

:return self.findfather(a)

== self.findfather(b)

defunion

(self, a, b)

:if a is

none

or b is

none

:return

afather = self.findfather(a)

bfather = self.findfather(b)

if(afather != bfather)

: anum = self.setnummap[afather]

bnum = self.setnummap[bfather]

if(anum <= bnum)

: self.fathermap[afather]

= bfather

self.setnummap[bfather]

= anum + bnum

self.setnummap.pop(afather)

else

: self.fathermap[bfather]

= afather

self.setnummap[afather]

= anum + bnum

self.setnummap.pop(bfather)

class

node

(object):

def__init__

(self, name, size, links)

: self.name = name

self.size = size

self.links = links

def__repr__

(self)

:return

"(節點:"

+str

(self.name)

+", 大小:"

+str

(self.size)

+", 連線到:"

+str

(self.links)

+")"

class

graph

(object):

def__init__

(self)

: self.edges =

self.nodes =

set(

) self.sizes =

dict

(map

=int

) self._edgessets =

#識別重複邊

defaddnode

(self, node)

: self.nodes.add(node)

self.sizes[node.name]

= node.size

defcalcedgeweights

(self)

:for node in self.nodes:

for link in node.links:

edge =(-

(node.size + self.sizes[link]

), node.name, link)

#邊權為負構造大頂堆

sedge =

if sedge not

in self._edgessets:

defrescue

(self)

: forest = unionfindset(self.sizes.keys())

edges = self.edges.copy(

) cost =

0while edges:

if forest.issameset(edge[1]

, edge[2]

): cost -= edge[0]

else

: forest.union(edge[1]

, edge[2]

)return cost

def__repr__

(self)

:return

"圖資訊:\n邊: "

+str

(self.edges)

+"\n點: "

+str

(self.nodes)

if __name__ ==

'__main__'

: n =

int(

input()

) graph = graph(

)while n:

m =int(

input()

)while m:

no, size, edgecnt =

map(

int,

input()

.split())

links =

[int

(x)for x in

input()

.split()]

graph.addnode(node(no, size, links)

) m -=

1 graph.calcedgeweights(

)#print(graph)

mincost = graph.rescue(

)#print("最小兵力:", mincost)

print

(mincost)

n -=

1

最大生成樹

problem a 古老的羊皮卷 time limit 3 sec memory limit 128 mb description 奇奇,乙個響亮的名字在acm界.如今奇奇已經腰纏萬貫,飛黃騰達,日子過的是無比的滋潤.是什麼使他到了如此的地位?如果你要這麼問,奇奇會不假思索的告訴你 acm 是acm...

最大生成樹

include define pp make pair using namespace std typedef long long ll const int maxn 1e6 30 const int n 260000 const ll mod 1e9 7 const int inf 0x3f3f3...

最大生成樹

最大生成樹演算法和最小生成樹演算法幾乎一樣,只需要我們把最小生成樹演算法進行一點點改變即可。當你用krushal演算法求最小生成樹的時候,每一次選取的邊都是最小的邊,然後再去判斷這條邊是否可以加入最小生成樹 那麼當你每一次選擇的邊是最大的邊,然後再去判斷這條邊是否可以加入,那麼這就是最大生成樹的求取...