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
输出
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 ; }