ACM/ICPC 之 Prim范例(ZOJ1586-POJ1789(ZOJ2158))

  两道Prim解法范例题型,简单的裸Prim,且两题相较以边为重心的Kruskal解法而言更适合以点为重心扩展的Prim解法。



ZOJ1586-QS Network

  题意:见Code

  题解:直接的MST题型,本题的图为稠密图,因此适合以点为扩展导向的Prim算法(代码量也较少)。

     大抵是先以某点A为中心,标记点A,访问其邻接点,更新全图到该点的距离(不通路以INF表示),找出最短距离的点B

     标记最短距离的B点,然后访问其邻接点,更新邻接点到B点的最短距离,找出最短距离的点C...以此类推...

     将已标记的点作为生成树M节点,此时M就是所求最小生成树。

     该算法的实际核心可以理解为每次更新所有未加入生成树M的点到集合M(将M理解为一个整体)的最短距离

     因此该算法普遍将该最短距离简化为一个数组,教材上一般命名为lowcost[MAX],不断更新此数组的最小值即可。

  

 1 //Prim-裸
 2 //建立QS网络,一条网线需要一定成本及两点处的适配器成本,求最小费用
 3 //本题的边数可到10^6,而点只到10^3,因此理论上说用prim比Kruskal明智(也比较好写)
 4 //Time:30Ms    Memory:4228K
 5 #include<iostream>
 6 #include<cstring>
 7 #include<cstdio>
 8 #include<algorithm>
 9 using namespace std;
10
11 #define INF 0x3f3f3f3f
12 #define MAX 1005
13
14 int n;
15 int d[MAX][MAX];
16 int adapter[MAX];    //适配器价格
17 int lowcost[MAX];    //各点到已生成集合的最小路长
18 bool v[MAX];    //已访问的点
19
20 void prim()
21 {
22     memset(lowcost, INF, sizeof(lowcost));
23     memset(v, false, sizeof(v));
24
25     int minv = 0;
26     v[0] = true;
27     for (int i = 1; i < n; i++)
28         lowcost[i] = d[i][0];
29     for (int i = 1; i < n; i++)
30     {
31         int mind = INF;
32         int k;    //最近的结点编号
33         for (int j = 0; j < n; j++)
34         {
35             if (!v[j] && mind > lowcost[j])
36             {
37                 mind = lowcost[j];
38                 k = j;
39             }
40         }
41
42         minv += mind;
43         v[k] = true;
44         for (int j = 0; j < n; j++)
45             if(!v[j])    lowcost[j] = min(lowcost[j], d[k][j]);
46     }
47     printf("%d\n", minv);
48 }
49
50 int main()
51 {
52     int T;
53     scanf("%d", &T);
54     while (T--)
55     {
56         scanf("%d", &n);
57         for (int i = 0; i < n; i++)
58             scanf("%d", &adapter[i]);
59         for (int i = 0; i < n; i++)
60             for (int j = 0; j < n; j++)
61             {
62                 scanf("%d", &d[i][j]);
63                 d[i][j] += adapter[i] + adapter[j];
64             }
65         prim();
66     }
67     return 0;
68 }


POJ1789(ZOJ2158)-Truck History

  题意:由7位编码组成的卡车编码,两个编码间的距离以对应位置的编码不同个数为总距离,例如aaaaaaa,abaabaa两个编码距离为2,求使得所有卡车编码最近的距离。(与实际题意有一点不同,为了方便理解稍微改编了一些)

  题解:理解了题意就好做了,本质依然是求一个裸的MST。

     Prim算法思路参照上题题解。

 1 //Prim-裸
 2 //POJ1789-ZOJ2158
 3 //边数4*10^6,点2000,稠密图较适合Prim
 4 //Time:657Ms    Memory:15872K
 5 #include<iostream>
 6 #include<cstring>
 7 #include<cstdio>
 8 #include<algorithm>
 9 using namespace std;
10
11 #define INF 0x3f3f3f3f
12 #define MAX 2001
13
14 int n;
15 int d[MAX][MAX];
16 int lowcost[MAX];
17 bool v[MAX];
18 char s[MAX][8];
19
20 void prim()
21 {
22     memset(lowcost, INF, sizeof(lowcost));
23     memset(v, false, sizeof(v));
24     int minv = 0;
25     v[0] = true;
26     for (int i = 0; i < n; i++)
27         lowcost[i] = d[i][0];
28     for (int i = 1; i < n; i++)
29     {
30         int mind = INF;
31         int k;
32         for (int j = 0; j < n; j++)
33         {
34             if (!v[j] && mind > lowcost[j])
35             {
36                 mind = lowcost[j];
37                 k = j;
38             }
39         }
40         minv += mind;
41         v[k] = true;
42         for (int j = 0; j < n; j++)
43             if (!v[j]) lowcost[j] = min(lowcost[j], d[k][j]);
44     }
45     printf("The highest possible quality is 1/%d.\n", minv);
46 }
47
48 int main()
49 {
50     while (scanf("%d", &n), n)
51     {
52         for (int i = 0; i < n; i++)
53             scanf("%s", s[i]);
54         memset(d, 0, sizeof(d));
55         for (int i = 0; i < n; i++)
56             for (int j = i+1; j < n; j++)
57                 for (int k = 0; k < 7; k++)
58                     d[j][i] = d[i][j] += s[i][k] != s[j][k];
59         prim();
60     }
61     return 0;
62 }
时间: 2024-10-13 00:20:29

ACM/ICPC 之 Prim范例(ZOJ1586-POJ1789(ZOJ2158))的相关文章

ACM/ICPC 之 Kruskal范例(POJ1128(ZOJ1083))

最小生成树范例,Kruskal解法-以边为主体扩展最小生成树,需要利用并查集. ZOJ1203-Swordfish 题意:求n个给定平面坐标的城市中的一条平面距离上的最短路长(保留两位小数) 题解:这道题数据不是很大,用Kruskal和Prim等算法都能够做. Kruskal的算法思路是以边为主体扩展结点,即先选取权值最少的边,将两个不连通的端点加入到同一集合中(使其连通),舍去该边,接着找权值次小的,以此类推... 如果两个端点连通,则直接舍去该边. 因此可以先将所有边依据权值大小排序后,然后

ACM/ICPC 之 SPFA范例两道(POJ3268-POJ3259)

两道以SPFA算法求解的最短路问题,比较水,第二题需要掌握如何判断负权值回路. POJ3268-Silver Cow Party //计算正逆最短路径之和的最大值 //Time:32Ms Memory:360K #include<iostream> #include<cstring> #include<cstdio> #include<queue> #include<algorithm> using namespace std; #define

ACM/ICPC 之 BFS范例(ZOJ2913)

通过一道经典BFS例题阐述BFS思路 ZOJ2913-Bus Pass 题意:找一个center区域,使得center到所有公交线路最短,有等距的center则输出id最小的. 题解:经典的BFS,由公交线路最多只经过10*20个区域,而总区域数可达10^5个,因此应该从公交线路通过队列一层层向外扩展,最后判断一次center的位置即可. 1 //选定一个center使得其到所有公交线路最短 2 //对所有公交线路进行BFS(公交线路比其他区域少得多) 3 //Time:150Ms Memory

《ACM/ICPC 算法训练教程》读书笔记一之数据结构(堆)

书籍简评:<ACM/ICPC 算法训练教程>这本书是余立功主编的,代码来自南京理工大学ACM集训队代码库,所以小编看过之后发现确实很实用,适合集训的时候刷题啊~~,当时是听了集训队final的意见买的,感觉还是不错滴. 相对于其他ACM书籍来说,当然如书名所言,这是一本算法训练书,有着大量的算法实战题目和代码,尽管小编还是发现了些许错误= =,有部分注释的语序习惯也有点不太合我的胃口.实战题目较多是比较水的题,但也正因此才能帮助不少新手入门,个人认为还是一本不错的算法书,当然自学还是需要下不少

2014 ACM/ICPC Asia Regional Guangzhou Online Wang Xifeng&#39;s Little Plot HDU5024

一道好枚举+模拟题目.转换思维视角 这道题是我做的,规模不大N<=100,以为正常DFS搜索,于是傻乎乎的写了起来.各种条件限制模拟过程 但仔细一分析发现对每个点进行全部八个方向的遍历100X100X100^8 .100X100个点,每个点在走的时候8中选择,TLE 于是改为另一个角度: 以符合要求的点为拐弯点,朝两个垂直的方向走,求出最远的距离.这样只要对每个点各个方向的长度知道,组合一下对应的就OK. 避免了每个点深搜. PS:搜索的时候x,y写反了,导致构图出现问题,以后用[dy][dx]

HDU 5014 Number Sequence(2014 ACM/ICPC Asia Regional Xi&#39;an Online) 题解

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5014 Number Sequence Problem Description There is a special number sequence which has n+1 integers. For each number in sequence, we have two rules: ● ai ∈ [0,n] ● ai ≠ aj( i ≠ j ) For sequence a and sequ

hdu6206 Apple 2017 ACM/ICPC Asia Regional Qingdao Online

地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=6206 题目: Apple Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 530    Accepted Submission(s): 172 Problem Description Apple is Taotao's favouri

ACM ICPC 2008–2009 NEERC MSC A, B, C, G, L

这套题是我上周日, 就是前天打得一场组队赛, 题目不太好找 题目链接:http://codeforces.com/gym/100861 在virtual judge 上也可以提交哦! A ACM ICPC Rules: 题目大意: 有很多所高校参加预选赛, 并在预选赛取得了排名, 但是对于每所学校, 除了MSU有4个名额之外其他大学只有两个名额( 也就是说, 只有每个大学的前2名进决赛(MSU前四名)&& 最多有10个队伍进入决赛), 高中队伍不能进入决赛. 给出预选赛的排名, 输出可以进

2016 ACM/ICPC Asia Regional Shenyang Online 1007/HDU 5898 数位dp

odd-even number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 388    Accepted Submission(s): 212 Problem Description For a number,if the length of continuous odd digits is even and the length