python 使用 最大生成樹 解決 營救問題
題目描述
你是紅軍指揮官,在一場軍事演習中,你的部分軍隊被藍軍包圍了。藍軍包圍的方式如下
在上圖中,每個頂點表示藍軍的部隊,頂點中數字表示藍軍在此處的人數(千人),兩點間的邊表示藍軍兩個部隊間形成的火線,火線構成的圈即是一道包圍,一條火線的戰鬥力為其相連兩個部隊的人數和,也是你要進攻這條火線所要消耗的兵力。你可以同時進攻藍軍的多條火線,請以成本最低的方式打破藍軍包圍,營救被包圍的部隊,計算出所需要消耗的兵力數(千人)
輸入
- 輸入包含多個測試例。第一行是一個整數n,表示測試測試例數量。
- 對每個測試例:
第一行是一個正整數m(2<m≤200),是藍軍部隊數。
每個藍軍部隊有兩行:
一行3個正整數:i為部隊編號(0≤i≤m-1),ai為藍軍部隊人數(千人)(1≤ai≤100),bi為與該部隊能形成火線的部隊數量(1≤bi≤m-1)。
一行有bi個正整數,分別是與部隊i形成火線的部隊編號,數字間有空格。 - 至少有一個包圍。
輸出
每個測試例輸出一行,是一個正整數:打破包圍營救戰友的最小消耗兵力。
輸入樣例
1
3
0 1 2
1 2
1 2 2
0 2
2 3 2
0 1
輸出結果
3
解題思路
程式碼實現
使用並查集優化的Kruskal演算法實現
#!/usr/bin/env python3
#rescue.py
#fumiama 20201115
from heapq import heappop, heappush
class UnionFindSet(object):
def __init__(self, nodes):
self.fatherMap = {}
self.setNumMap = {}
for node in nodes:
self.fatherMap[node] = node
self.setNumMap[node] = 1
def findFather(self, node):
father = self.fatherMap[node]
if (node != father):
father = self.findFather(father)
self.fatherMap[node] = father
return father
def isSameSet(self, a, b):
return self.findFather(a) == self.findFather(b)
def union(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 = [] #識別重複邊
def addNode(self, node):
self.nodes.add(node)
self.sizes[node.name] = node.size
def calcEdgeWeights(self):
for node in self.nodes:
for link in node.links:
edge = (-(node.size + self.sizes[link]), node.name, link) #邊權為負構造大頂堆
sedge = {node.size + self.sizes[link], node.name, link}
if sedge not in self._edgesSets:
heappush(self.edges, edge)
self._edgesSets.append(sedge)
def rescue(self):
forest = UnionFindSet(self.sizes.keys())
edges = self.edges.copy()
cost = 0
while edges:
edge = heappop(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
相關文章
- 解決 Python 指令碼無法生成結果的問題Python指令碼
- [Leetcode]827.使用回溯+標記解決最大人工島問題LeetCode
- 一類生成樹計數問題。
- 回溯法(排列樹)解決八(N)皇后問題
- pyinstaller 生成 exe 的閃退問題解決方案
- Python 解決 :NameError: name 'reload' is not defined 問題PythonError
- 徹底解決Python編碼問題Python
- 使用動態規劃完美解決硬幣找零問題(Python)動態規劃Python
- 貨車運輸(LCA+最大生成樹)
- Python的Selenium一些問題解決Python
- Python自動生成10000個java類使用APT註解後引發的問題PythonJavaAPT
- 解決無法使用VI的問題
- 一個簡單的統計問題(解決方案:Trie樹)
- python json.dumps中文亂碼問題解決PythonJSON
- VSCode中解決python模組匯入問題VSCodePython
- Python執行緒安全問題及解決方法Python執行緒
- 解決Visual Studio(2017)軟體無法重新生成問題
- 動態生成html元素繫結事件iphone失效問題解決HTML事件iPhone
- 前端生成海報圖技術選型與問題解決前端
- 教你如何使用PyTorch解決多分類問題PyTorch
- Mysql使用kill命令解決死鎖問題MySql
- Nuxt使用axios跨域問題解決方法UXiOS跨域
- 01 Eclipse使用Maven慢的問題解決EclipseMaven
- 使用Nginx來解決跨域的問題Nginx跨域
- 【技術分享】如何使用FMEA解決問題?
- 【問題解決】使用YYYY-MM-dd時間轉換問題
- 前端必會演算法 - 最小生成樹問題前端演算法
- 【演算法學習筆記】生成樹問題探究演算法筆記
- 最大數問題
- 決策樹減支問題(優化)dfs減支問題優化
- Python 3.6.10 中的 requests 庫 TLS 1.2 強制使用問題及解決方案PythonTLS
- 決策樹模型(3)決策樹的生成與剪枝模型
- idea 使用日常問題 使用maven外掛 打包沒問題 但是使用 mvn命令打包失敗的問題解決IdeaMaven
- linux mint 19 pyenv 安裝 python 3.7.0 問題解決LinuxPython
- Linux解決MySQL-python安裝失敗問題LinuxMySqlPython
- 【譯】Python 是解決任何問題的完美工具Python
- 解決 macOS 下 Python 3.8 安裝 mysqlclient 的問題MacPythonMySqlclient
- Linux安裝Python3.11以及解決openssl問題LinuxPython