Farmer John已经决定把水灌到他的n(1≤n≤300)块农田,农田被数字1到n标记。把一块土地进行灌水有两种方法,从其他农田饮水,或者这块土地建造水库。 建造一个水库需要花费wi(1≤wi≤105),连接两块土地需要花费pij。 计算Farmer John所需的最少代价。 输入描述:
第一行:一个数n。
第二行到第n+1行:第i+1行含有一个数wi。
第n+2行到第2∗n+1行:第n+1+i行有n个被空格分开的数,第j个数代表pij。
输出描述:
一个单独的数代表最小代价.
示例1 输入
4 5 4 4 3 0 2 2 2 2 0 3 3 2 3 0 4 2 3 4 0
输出
9
guanshui.cpp view raw 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 #include <iostream> #include <vector> #include <algorithm> using namespace std ;const int N = 310 ;int fa[N];struct Edge { int a, b, v; }edges[N*N]; int n;int tot;int find (int x) { if (x==fa[x]) return x; return fa[x] = find (fa[x]); } bool cmp (Edge &a, Edge&b) { return a.v < b.v; } int main () { scanf ("%d" , &n); int val; for (int i=1 ;i<=n;i++){ scanf ("%d" , &val); edges[++tot].a = 0 , edges[tot].b = i, edges[tot].v = val; } for (int i=1 ;i<n;i++) for (int j=1 ;j<=n;j++){ scanf ("%d" , &val); if (i<j) edges[++tot].a= i, edges[tot].b = j, edges[tot].v = val; } for (int i=0 ;i<=n;i++) fa[i] = i; int ans = 0 ; sort(edges+1 , edges+tot+1 , cmp); for (int i=1 ;i<=tot;i++){ int a = find (edges[i].a); int b = find (edges[i].b); if (a!=b) fa[a] = b, ans += edges[i].v; } printf ("%d\n" , ans); return 0 ; }