【解题报告】 HDU 1102 Constructing Roads -- 并查集 最小生成树 Prime算法
2012-08-02 22:27
483 查看
题目连接:HDU 1102
题目大意:自己看。代码写的很长,主要想练二叉堆来实现优先队列,毕竟学了就得用上。
题目大意:自己看。代码写的很长,主要想练二叉堆来实现优先队列,毕竟学了就得用上。
// HDU 1102 Constructing Roads -- 并查集 最小生成树 Prime算法 // 二叉堆 -- 用于优先队列的实现 // 完全二叉树的 I 结点的 两个 child 是 I*2 and I*2+1 . // 完全二叉树的 I 结点的 father 是 I/2 . // 队列结构 -> head -> queue -> bottom -> // #include <cstdio> #include <iostream> using namespace std; const int MAXV = 105; const int MAXVIA = 10005; struct VIA{ int cost,a,b; }prority_queue[MAXVIA]; int head; // 只需要队列入口的指向 int father[MAXV]; // 村庄的father int num[MAXV]; // 记录集合中元素的个数 int cost[MAXV][MAXV]; bool flag[MAXV]; // 标记一个村庄是否 入队过了,实质是记录方向 void swap(VIA& a,VIA& b){ a.a^=b.a^=a.a^=b.a; a.b^=b.b^=a.b^=b.b; a.cost^=b.cost^=a.cost^=b.cost; } bool is_empty(){ return !(head - 1); } void InQueue(int cost,int a,int b){ int node = head; int father = node /2 ; // /2 prority_queue[head].a = a; prority_queue[head].b = b; prority_queue[head++].cost = cost; while(prority_queue[node].cost < prority_queue[father].cost){ swap(prority_queue[node], prority_queue[father]); node = father; father = node /2 ; // /2 } // ensure right child bigger than left child, impossible!! } VIA DeQueue(){ VIA val = prority_queue[1]; // the bottom of queue int node = 1; VIA temp_head = prority_queue[--head]; // let the head element out queue while(node*2 < head){ int temp_node = node; // save father node node = node << 1; // *2 if (node+1 == head || prority_queue[node].cost < prority_queue[node+1].cost) // choose the smaller rise swap(prority_queue[node],prority_queue[temp_node]); else{ swap(prority_queue[node+1],prority_queue[temp_node]); node = node + 1; } } prority_queue[node] = temp_head; // make the original element into the blank site int father = node /2 ; // /2 adjust the element to a appropriate site while(prority_queue[node].cost < prority_queue[father].cost){ swap(prority_queue[node], prority_queue[father]); node = father; father = node /2 ; // /2 } prority_queue[head].cost = 0; prority_queue[head].a = 0; prority_queue[head].b = 0; return val; } void init(int n){ head = 1; // queue start with '1' for (int i = 0 ;i < MAXVIA ; i++){ prority_queue[i].a = 0; prority_queue[i].b = 0; prority_queue[i].cost = 0; } memset(cost,0,sizeof(cost)); memset(father,-1,sizeof(father)); memset(flag,true,sizeof(flag)); for (int i=0;i<MAXV;num[i]=1,i++); for (int i = 1; i <= n; i++){ for (int j = 1; j <= n; j++){ scanf("%d",&cost[i][j]); cost[j][i] = cost[i][j]; } } } int find (int x){ if (father[x] <= 0) return x; return father[x] = find(father[x]); } void combination(int a,int b){ father[b] = a; if (father[a]<0)father[a] = 0; num[a] += num[b]; } int Prime_MST(int n){ // 类似于广搜 int sum = 0; for (int i = 2; i <= n; i++){ // 第一层入队 int ra = find(i); int rb = find(1); if (ra != rb) InQueue(cost[i][1], i, 1); // 只有不在一个集合中才 入队候选 } flag[1] = false; while( !is_empty() ){ VIA temp; temp = DeQueue(); int ra = find(temp.a); int rb = find(temp.b); if (ra != rb){ sum += temp.cost; combination(ra,rb); if (num[ra]==n) return sum; // 当存在一个集合中的元素个数等于villages总数时 int in; if (flag[temp.a]) in = temp.a; // 判断方向 else in = temp.b; for (int i = 1; i <= n; i++){ // 下一层入队 int rra = find(in); int rrb = find(i); if (rra != rrb) InQueue(cost[i][in],i,in); // 只有不在一个集合中才 入队候选 } } } return sum; } int main() { // freopen("in.txt","r",stdin); int n_villages; while(scanf("%d",&n_villages) != EOF){ init(n_villages); // 价格表 int n_conn,a,b; scanf("%d",&n_conn); for (int i = 1;i <= n_conn; i++){ scanf("%d %d",&a,&b); int ra = find(a); int rb = find(b); if (ra != rb){ //combination(ra,rb); cost[a][b]=0;cost[b][a]=0; //如果连通把价格设为 0 } } // 计算预算 cout << Prime_MST(n_villages) << endl; } return 0; }
相关文章推荐
- poj 3228 Gold Transportation 最小生成树+带权并查集 解题报告
- hdu 1102 最小生成树 prim算法+Kruskal算法(并查集)
- hdu 1102 (最小生成树kruskal算法--并查集,prim死活过不了)
- 最小生成树,POJ和HDU几道题目的解题报告(基于自己写的模板)
- **HDU-1233 还是通畅工程 ACM解题报告(kruskal+并查集求最小生成树)
- Hdu 1879 继续畅通工程 最小生成树 解题报告
- 【解题报告】 HDU 1875 畅通工程再续 Kruskal最小生成树 一点关于浮点型在计算机中储存的分析
- 最小生成树,POJ和HDU几道题目的解题报告(基于自己的模板)
- 并查集+最小生成树_HDU_1102
- HDU 1232 - 并查集 解题报告
- 【最小生成树+Prim】杭电 hdu 1102 Constructing Roads
- Pku acm 2485 Highways数据结构题目解题报告(三) ----最小生成树:prim算法
- HDU 1102 最小生成树 prim
- HDU 1233 最小生成树和并查集
- hdu1102 - Constructing Roads (求最小生成树) (Prim & Kruskal)
- 洛谷 1195 口袋的天空 最小生成树 解题报告
- POJ3522 Slim Span 解题报告【Kruskal求最小生成树+枚举】
- BZOJ 1682 [Usaco2005 Mar] 最小生成树 解题报告
- 解题报告之——hdu1233还是畅通工程(最小生成树)
- hdu 1102 Constructing Roads 最小生成树