hdu1879 继续畅通工程 最小生成树
2013-03-20 18:46
274 查看
继续畅通工程
此题明显属于最小生成树的题目关于最小生成树,有两种方法,一种是Kruskal方法,一种是Prim算法,第一种用并查集即可实现
/* hdu1879 2013-03-18 15:25:50 Accepted 1879 406MS 360K 1188 B 典型的最小生成树,在做并查集时做的这道题, 所以使用并查集实现的克鲁斯卡尔算法 */ #include <iostream> #include <stdio.h> #include <algorithm> using namespace std; struct node { int start ,end,expense,flag; }data[5005]; int father[105]; void make_set(int n) { for(int i=1;i<=n;i++) father[i]=i; } int find_set(int x) { if(x^father[x]) father[x]=find_set(father[x]); return father[x]; } int union_set(int x,int y) { x=find_set(x); y=find_set(y); if(x==y) return 0; father[x]=y; return 1; } bool cmp(node a,node b) { return a.expense<b.expense; } int main() { int n; while(scanf("%d",&n)!=EOF) { if(!n) break; make_set(n); int ans=0; int m=(n-1)*n/2; for(int i=0;i<m;i++) { scanf("%d%d%d%d",&data[i].start,&data[i].end,&data[i].expense,&data[i].flag); if(data[i].flag)//当道路修通时,规定一节点为另一节点的父亲 father[data[i].start]=data[i].end; } sort(data,data+m,cmp);//按道路的花费升序排列 //在不构成环的前提下,选择最短的边,有贪心的思想 for(int i=0;i<m;i++) { if(union_set(data[i].start,data[i].end)) ans+=data[i].expense; } printf("%d\n",ans); } return 0; }
第二种则需要开辟一个二维邻接矩阵实现
/* hdu1879 2013-03-20 17:30:48 Accepted 1879 187MS 324K 1496 B 最小生成树的prim算法, */ #include <iostream> #include <stdio.h> #include <string.h> using namespace std; int n; int low[110];//存储将要联通的候选边 int visited[110];//是否已经并入联通集合 int map[110][110];//二维矩阵存储图 const int maxn=0x3fffffff;//无穷大 int prim() { int min; int pos=0,ans=0; memset(visited,0,sizeof(visited)); visited[pos]=1;//从第一个点开始联通 for(int i=0;i<n;i++)//循环初始化 { if(!visited[i]) { low[i]=map[pos][i]; } } for(int i=1;i<n;i++) { min=maxn; for(int j=0;j<n;j++) { if(min>low[j]&&!visited[j]) { min=low[j];//找到所有可连通边中的最短边 pos=j;//找到将要并入的下一个点 } } ans+=min; visited[pos]=1; for(int j=0;j<n;j++)//新点并入后更新最短边候选集合 { if(!visited[j]&&map[pos][j]<low[j]) low[j]=map[pos][j]; } } return ans; } int main() { while(scanf("%d",&n)!=EOF) { if(!n)break; int a,b,c,d; int m=(n-1)*n/2; for(int i=0;i<m;i++) { scanf("%d%d%d%d",&a,&b,&c,&d); if(d)//若两点已经连通,不需新建道路,花费为零 { map[a-1][b-1]=map[b-1][a-1]=0; } else map[a-1][b-1]=map[b-1][a-1]=c; } printf("%d\n",prim()); } return 0; }
相关文章推荐
- HDU1879-继续畅通工程(Prim算法+Kruskal算法)
- hdu1879 继续畅通工程--prim
- HDU1879继续畅通工程
- 继续畅通工程--hdu1879(最小生成树 模板题)
- hdu1879继续畅通工程(并查集+Kruskal,Kruskal模板题)
- 最小生成树 克丽丝卡尔算法 hdu1879 继续畅通工程
- HDU1879 继续畅通工程
- hdu1879继续畅通工程
- hdu1879继续畅通工程 最小生成树prim算法
- hdu1879继续畅通工程
- HDU 1879 继续畅通工程-最小生成树
- hdu1879 继续畅通工程(最小生成树)
- hdu1879 继续畅通工程
- hdu1879继续畅通工程(最小生成树kru算法)
- ACM-最小生成树之继续畅通工程——hdu1879
- hdu1879 继续畅通工程 (kruskal求最小生成树)
- Hdu1879 - 继续畅通工程 - 最小生成树
- HDU1879继续畅通工程
- HDU1879继续畅通工程
- 继续畅通工程(hdu1879)并查集