P1550 [USACO08OCT] Watering Hole G
P1550 [USACO08OCT] Watering Hole G
题目描述
Farmer John 的农场缺水了。
他决定将水引入到他的 nnn 个农场。他准备通过挖若干井,并在各块田中修筑水道来连通各块田地以供水。在第 iii 号田中挖一口井需要花费 WiW_iWi 元。连接 iii 号田与 jjj 号田需要 Pi,jP_{i,j}Pi,j(Pj,i=Pi,jP_{j,i}=P_{i,j}Pj,i=Pi,j)元。
请求出 FJ 需要为使所有农场都与有水的农场相连或拥有水井所需要的最少钱数。
输入格式
第一行为一个整数 nnn。
接下来 nnn 行,每行一个整数 WiW_iWi。
接下来 nnn 行,每行 nnn 个整数,第 iii 行的第 jjj 个数表示连接 iii 号田和 jjj 号田需要的费用 Pi,jP_{i,j}Pi,j。
输出格式
输出最小开销。
输入输出样例 #1
输入 #1
4
5
4
4
3
0 2 2 2
2 0 3 3
2 3 0 4
2 3 4 0
输出 #1
9
说明/提示
对于 100%100\%100% 的数据,1≤n≤3001 \leq n \leq 3001≤n≤300,1≤Wi≤1051 \leq W_i \leq 10^51≤Wi≤105,0≤Pi,j≤1050 \leq P_{i,j} \leq 10^50≤Pi,j≤105。
对于这题,每个田地有两个操作:打井或连接。既然如此,我们可以将井水看作一个虚拟点,每块田地与其相连的代价为 WiW_iWi。随后跑MST即可。
#include<bits/stdc++.h>
using namespace std;int main(){int n;cin>>n;vector<vector<int>> g(n, vector<int>(n+1, 0));for(int i = 0;i<n;i++){cin>>g[i][n];}for(int i = 0;i<n;i++){for(int j = 0;j<n;j++){cin>>g[i][j];}}vector<int> dist(n, 1e9);vector<bool> vis(n, false);for (int i = 0; i < n; i++) {dist[i] = g[i][n];}int ans = 0;for (int it = 0; it < n; it++) {int u = -1;for (int i = 0; i < n; i++) {if (!vis[i] && (u == -1 || dist[i] < dist[u])) {u = i;}}vis[u] = true;ans += dist[u];for (int v = 0; v < n; v++) {dist[v] = min(g[u][v], dist[v]);}}cout << ans;return 0;
}