zoukankan      html  css  js  c++  java
  • zoj1586 QS Network ——最小生成树入门题_Prim算法

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=586

    题目大意:

      题目意思比较难懂。看书上的翻译竟然没有看懂,还是打开OJ,看英文的原题。看了两遍的样子,终于差不多懂了。

      QS是一种生物,要完成通信,需要设备,每个QS需要的设备的价格不同,并且,这种设备只能在两个QS之间用一次,也就是说,如果一个QS需要和3个QS通信的话,它就必须得买3个设备,同时,对方三个也必须买对应的适合自己的设备。同时,每两个QS之间是有距离的,要完成通信还需要网线,给出每两个QS之间的网线的价值。求一棵生成树,使得所需要的费用最少。数据范围:所有数据都在1000以内。

    题目思路:

      根据这种设备的特性,每个设备只能和另外一个QS通信,所以呢,建图的时候,每条边的权值就是网线的费用,加上这条边的两个端点的QS所需设备的费用的和。这样,就转化成了常规的最小生成树的问题。因为只需要求出最小费用,所以,可以不必记录prim过程中要选的边的顶点编号,也就是说,可以省略nearvex数组,用lowcost数组就可以实现。如果lowcost[i]的值是-1,则代表已经选择了这个点,否则,lowcost[i]依然表示集合T1内的顶点 i 距离集合T内个顶点权值最小的边的权值。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cctype>
     6 #include <stack>
     7 #include <queue>
     8 #include <map>
     9 #include <set>
    10 #include <vector>
    11 #include <cmath>
    12 #include <algorithm>
    13 #define lson l, m, rt<<1
    14 #define rson m+1, r, rt<<1|1
    15 using namespace std;
    16 typedef long long int LL;
    17 const int MAXN =  0x3f3f3f3f;
    18 const int  MIN =  -0x3f3f3f3f;
    19 const double eps = 1e-9;
    20 const int dir[8][2] = {{0,1},{1,0},{0,-1},{-1,0},{-1,1},
    21   {1,1},{1,-1},{-1,-1}};
    22 const int MAX = 1000+10;
    23 int edge[MAX][MAX], lowcost[MAX];
    24 int t, n, pri[MAX];
    25 void prim(int u0) 
    26 {
    27   int sum = 0, i, j, v;
    28   for (i = 1; i <= n; ++i) lowcost[i] = edge[u0][i];
    29   lowcost[u0] = -1;
    30   for (i = 1; i < n; ++i) {
    31     int min = MAXN; v = -1;
    32     for (j = 1; j <= n; ++j) {
    33       if (min > lowcost[j] && lowcost[j] != -1) {
    34         v = j; min = lowcost[j];
    35       }
    36     }
    37     if (v != -1) {
    38       sum += lowcost[v]; lowcost[v] = -1;
    39       for (j = 1; j <= n; ++j) {
    40         if (edge[v][j] < lowcost[j] && lowcost[j] != -1) {
    41           lowcost[j] = edge[v][j];
    42         }
    43       }
    44     }
    45   }
    46   printf("%d\n", sum);
    47 }
    48 int main(void){
    49 #ifndef ONLINE_JUDGE
    50   freopen("zoj1568.in", "r", stdin);
    51 #endif
    52   scanf("%d", &t);
    53   int i, j, k;
    54   while (t--) {
    55     memset(edge, 0, sizeof(edge));
    56     scanf("%d", &n);
    57     for (i = 1; i <= n; ++i) scanf("%d", &pri[i]);
    58     for (i = 1; i <= n; ++i) {
    59       for (j = 1; j <= n; ++j) {
    60         scanf("%d", &edge[i][j]);
    61         edge[i][j] += (pri[i] + pri[j]);
    62       }
    63     }
    64     prim(1);
    65   }
    66 
    67   return 0;
    68 }

    写这道题目的时候,遇到一个比较坑的问题,导致输出怎么也不出结果。。。后来才发现,读文件那句话里的文件名写错了……好吧……我去……

  • 相关阅读:
    QT自定义控件插件化简要概述
    wildfly9 配置SSL单向认证/https
    wildfly-9.0.2 web项目部署详细步骤
    SQL Server 2008 数据库日志文件丢失处理方法
    win7 64位系统 pl/sql 无法解析指定的连接标识符解决办法
    mybatis 应用参考
    去除浏览器下jquey easyui datagrid、combotree 缓存问题
    java 页面url传值中文乱码的解决方法
    jasperreports-5.6 + jaspersoftstudio-5.6 生成pdf 文件中文无法正常显示问题
    HTML5实现在线抓拍
  • 原文地址:https://www.cnblogs.com/liuxueyang/p/3055772.html
Copyright © 2011-2022 走看看