[2016-04-14][ZOJ][1586][QS Network]

  • 时间:2016-04-14 21:02:17 星期四

  • 题目编号:[2016-04-14][ZOJ][1586][QS Network]

  • 题目大意:给定一个n个用户,每个用户之间连接需要线路和adapter,每个连接两端各需要一个adapter,把n个节连接起来至少需要多少代价唉

  • 分析:

    • 直接prim或者kruskal
    • 这里的总代价=边权+两个端点的点权,存图的时候可以直接加进去,也可以后面算法的时候计算
  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. using namespace std;
  5. const int maxn = 1000 + 10;
  6. int g[maxn][maxn],lowc[maxn],vis[maxn],v[maxn];
  7. int prim(int n){
  8. int ans = 0;
  9. memset(vis,0,sizeof(vis));
  10. vis[0] = 1;
  11. for(int i = 1; i< n ; ++i) lowc[i] = g[0][i] + v[0] + v[i];
  12. for(int i = 1 ; i < n ; ++i){
  13. int minc = 0x3f3f3f3f;
  14. int p = -1;
  15. for(int j = 0 ; j < n ; ++j){
  16. if(!vis[j] && minc > lowc[j]){
  17. minc = lowc[j];
  18. p = j;
  19. }
  20. }
  21. if(minc == 0x3f3f3f3f) return -1;
  22. ans += minc;
  23. vis[p] = 1;
  24. for(int j = 0; j < n ; ++j){
  25. if(!vis[j] && lowc[j] > g[p][j] + v[p] + v[j]){
  26. lowc[j] = g[p][j] + v[p] + v[j];
  27. }
  28. }
  29. }
  30. return ans;
  31. }
  32. int main(){
  33. int t;
  34. scanf("%d",&t);
  35. while(t--){
  36. int n,a;
  37. scanf("%d",&n);
  38. memset(g,0x3f,sizeof(g));
  39. for(int i = 0 ; i < n ; ++i){
  40. scanf("%d",&v[i]);
  41. }
  42. for(int i = 0 ; i < n ; ++i){
  43. for(int j = 0 ; j < n ; ++j){
  44. scanf("%d",&a);
  45. g[i][j] = min(g[i][j],a);
  46. }
  47. }
  48. printf("%d\n",prim(n));
  49. }
  50. return 0;
  51. }


来自为知笔记(Wiz)


posted on 2016-04-14 21:07  红洋  阅读(161)  评论(0)    收藏  举报

导航