###### tags: `APCS` # **f606-流量** ### **題目連結:** [**f606**](https://zerojudge.tw/ShowProblem?problemid=f606) ### **題目解析** 有 \( n \) 個伺服器編號從 0 到 \( n-1 \),以及 \( m \) 個城市編號從 0 到 \( m-1 \)。每個伺服器需要傳送資料到各城市,已知每個伺服器 \( i \) 傳送到城市 \( j \) 的流量為 \( Q[i][j] \)。 工程師正在規劃將伺服器搬遷到城市中,對於一個方案 \( c = (c_1, c_2, ..., c_n) \),表示編號 \( i \) 的伺服器要放在城市 \( c_i \)。 城市之間資料傳輸是需要費用的。若城市 \( u \) 要傳送資料到城市 \( v \),費用的計算法如下: - 若 \( u = v \),單位流量需要 1 塊錢。 - 若 \( u != v \),小於等於 1000 的流量每單位 3 塊錢,大於 1000 的部分每單位 2 塊錢。 若某伺服器有多個城市需要傳送資料到城市 \( u \),會先將這些總量相加再計算費用。 工程師們總共提出了 \( k \) 種方案,請你找出花費最少的方案所需的費用。 ### **解題方向** 1. 解析輸入資料,讀取伺服器數量 \( n \)、城市數量 \( m \)、方案數量 \( k \) 以及每個伺服器對每個城市的流量矩陣 \( Q \)。 2. 建立並初始化花費列表 \( cost \)。 3. 對每個方案計算伺服器配置的流量矩陣 \( flow \)。 4. 根據流量計算每個方案的總費用。 5. 找出最小費用並輸出。 ### **程式解析** 1. 輸入與初始化 ```python3 n, m, k = map(int, input().split()) ``` * 這行程式碼從輸入中讀取三個整數n、m、k,分別表示伺服器的數量、城市的數量和方案的數量。 2. 讀取流量矩陣Q ```python Q = [] for i in range(n): row = list(map(int, input().split())) Q.append(row) ``` * 這段程式碼從輸入中讀取n行,每行包含m個整數,存儲在二維列表Q中。這表示每個伺服器到每個城市的流量。 3. 初始化花費列表 ```python cost = [0 for i in range(k)] ``` * 這行程式碼初始化一個列表cost,用來存儲每個方案的總花費,初始值全部設為 0。 4. 計算每個方案的花費 ```python for i in range(k): c = list(map(int, input().split())) # 讀取一個方案 flow = [[0 for x in range(m)] for y in range(m)] # 初始化流量矩陣 # 計算流量 for x in range(n): for y in range(m): flow[c[x]][y] += Q[x][y] # 計算花費 for x in range(m): for y in range(m): if x == y: cost[i] += flow[x][y] else: if flow[x][y] <= 1000: cost[i] += flow[x][y] * 3 else: cost[i] += 1000 * 3 cost[i] += (flow[x][y] - 1000) * 2 ``` * 這段程式碼對每個方案進行以下步驟: * 讀取一個方案c,表示每個伺服器的位置。 * 初始化一個新的流量矩陣flow,用來存儲每個城市到其他城市的總流量。 * 遍歷每個伺服器x到每個城市y的流量,將其加到flow 矩陣中對應的位置。 * 根據流量矩陣flow 計算每個城市間的傳輸費用並累加到總花費中: * 若伺服器與城市相同,則每單位流量費用為 1。 * 若伺服器與城市不同,根據流量大小計算費用,小於等於 1000 的部分每單位 3 塊錢,大於 1000 的部分每單位 2 塊錢。 5. 找出最小花費並輸出 ```python min_cost = min(cost) print(min_cost) ``` * 這段程式碼找出所有方案中花費最小的方案,並輸出最小花費。 ### **完整程式碼** ```python=1 def show_flow(arr, R, C): for i in range(R): for j in range(C): print(arr[i][j], end=' ') print() # ------------------------------------- # 儲存 n, m, k #start n, m, k = map(int, input().split()) # n -> Server數量 # m -> City數量 # k -> 方案數量 # 儲存Q Q=[] for i in range(n): # 畫出一個二維陣列(表格) row = list(map(int, input().split())) Q.append(row) # 初始化 cost(花費), 依據 k 種方案的結果 cost = [ 0 for i in range(k) ] # 儲存 k 種方案 => 讀入一種方案 => 得到總金額 => next for i in range(k): c=list(map(int,input().split())) # 有c1~cn # sever數量 n=m, n<m, n>m flow=[[0 for x in range(m)] for y in range(m)] # 流量有可能會需要重複計算, 加總流量 for x in range(n): for y in range(m): flow[c[x]][y] += Q[x][y] #show_flow(flow, m, m) # 計算 cost (真正的花費) for x in range(m): for y in range(m): # 伺服器與城鎮相同 if x == y: cost[i] += flow[x][y] else: if flow[x][y] <= 1000: cost[i] += flow[x][y]*3 else: cost[i] += 1000*3 cost[i] += (flow[x][y]-1000)*2 #print(cost[i]) min_cost = min(cost) print(min_cost) ```