poj1251
用的是Kruskal算法 以及并查集
#include "iostream" using namespace std; #define maxsize 110 typedef struct Edge { int weight;//权值 int node1;//顶点 int node2;//顶点 } Edge; Edge e[maxsize]; int vis[maxsize]; int putIn(int n) { //输入 char ch; int num; char ch1; int t; int i,j,k=0; for (i=0;i<n-1;i++) { cin>>ch>>num; for (j=0;j<num;j++) { cin>>ch1>>t; e[k].weight=t; e[k].node1=ch-65; e[k].node2=ch1-65; k++; } } return k;//边的个数 } int cmp( const void *a ,const void *b) { Edge *aa=(Edge*)a; Edge *bb=(Edge*)b; return aa->weight>bb->weight?1:-1; } void union_node(int i,int len) { //将e[i].node1的集合并入e[i].node2的集合 int j; int t=vis[e[i].node1];//要先将vis[e[i].node1保存下来 因为循环中会改变值 for (j=0;j<len;j++) { if (vis[j]==t) { vis[j]=vis[e[i].node2]; } } } int Kruskal(int len,int n) { int i,j; int ans=0; //vis数组用做并查集 for (i=0;i<n;i++)//i<len是错的 应该是村庄个数 { vis[i]=i;//表示第i个元素属于第i个集合 } for (i=0;i<len;i++) { if (vis[e[i].node1]!=vis[e[i].node2])//如果该边的两个顶点在不同的集合 { //将两点并入一个集合 union_node(i,len); //累加权值 ans+=e[i].weight; } } return ans; } int main() { int n; int i,j; while(cin>>n) { if(n==0) break; int len=putIn(n); //按权值从小到大排序 qsort(e,len,sizeof(e[0]),cmp); //Kruskal算法生成最小生成树 int ans=Kruskal(len,n); //输出结果 cout<<ans<<endl; } return 0; }
poj 1287
prim
#include "iostream" using namespace std; #define MAXSIZE 1500 #define MAX 99999999 int map[MAXSIZE][MAXSIZE]; int vis[MAXSIZE]; int temp[MAXSIZE]; int main() { int n,m; while (1) { scanf("%d",&n); if (n==0) { break; } scanf("%d",&m); int ans=0; int i,j; for (i=0;i<n;i++) { for (j=0;j<n;j++) { map[i][j]=MAX; } } for (i=0;i<m;i++) { int t1,t2,w; scanf("%d%d%d",&t1,&t2,&w); if (w<map[t1-1][t2-1]) map[t1-1][t2-1]=w; } for (i=0;i<m;i++) { for (j=0;j<m;j++) { if (map[i][j]<map[j][i]) { map[j][i]=map[i][j]; } } } memset(vis,0,sizeof(vis)); for (j=0;j<n;j++) { temp[j]=MAX; } i=0; for (j=0;j<n;j++) { if (map[i][j]!=0) if (map[i][j]<temp[j]) { temp[j]=map[i][j]; } } vis[0]=1; while (i<n-1) { //找最小的边 int min=MAX; int minindex=0; for (j=0;j<n;j++) { if (vis[j]==1) { continue; } if (min>temp[j]) { min=temp[j]; minindex=j; } } //把最小的边的顶点加入集合 vis[minindex]=1; //更新temp for (j=0;j<n;j++) { if (map[minindex][j]!=0&&vis[j]!=1) if (map[minindex][j]<temp[j]) { temp[j]=map[minindex][j]; } } ans+=min; i++; } printf("%d\n",ans); } return 0; }
poj 2395
与1251一样
#include "iostream" using namespace std; #define maxsize 10015 typedef struct Edge { int weight;//权值 int node1;//顶点 int node2;//顶点 } Edge; Edge e[maxsize]; int vis[maxsize]; void putIn(int n,int m) { int num=0; //输入 for (int i=0;i<m;i++) { int k1,k2,w; cin>>k1>>k2>>w; e[num].node1=k1; e[num].node2=k2; e[num].weight=w; num++; } //return m;//边的个数 } int cmp( const void *a ,const void *b) { Edge *aa=(Edge*)a; Edge *bb=(Edge*)b; return aa->weight>bb->weight?1:-1; } void union_node(int i,int len) { //将e[i].node1的集合并入e[i].node2的集合 int j; int t=vis[e[i].node1];//要先将vis[e[i].node1保存下来 因为循环中会改变值 for (j=0;j<len;j++) { if (vis[j]==t) { vis[j]=vis[e[i].node2]; } } } int Kruskal(int m,int n) { int i,j; int ans=0; //vis数组用做并查集 for (i=0;i<n;i++)//i<len是错的 应该是村庄个数 { vis[i]=i;//表示第i个元素属于第i个集合 } int count=0; int max=0; for (i=0;i<m;i++) { if (vis[e[i].node1]!=vis[e[i].node2])//如果该边的两个顶点在不同的集合 { //将两点并入一个集合 union_node(i,m); //累加权值 ans+=e[i].weight; if(max<e[i].weight) max=e[i].weight; count++; } if (count==n-1) { break; } } return max; } int main() { int n,m; int i,j; while(scanf("%d%d",&n,&m)!=EOF) { // cin>>n>>m; //cin>>m; putIn(n,m); //按权值从小到大排序 qsort(e,m,sizeof(e[0]),cmp); //Kruskal算法生成最小生成树 int ans=Kruskal(m,n); //输出结果 cout<<ans<<endl; } return 0; }
相关推荐
标题“poj1251 最小生成树”是一个编程竞赛题目,来源于著名的在线编程平台POJ(Programming Online Judge)。这个题目主要涉及图论中的一个经典算法问题——最小生成树(Minimum Spanning Tree, MST)。在图论中,...
对于这些题目,理解最小生成树的基本算法如 Prim 和 Kruskal 是关键,同时要注意根据具体问题的特性调整算法的应用。在实际编程时,还需要注意数据结构的选择,例如使用优先队列(二叉堆)优化 Prim 算法,或者使用...
构造最小生成树主要有两种经典算法:Prim算法和Kruskal算法。 **Prim算法** Prim算法是一种贪心算法,其基本思想是从某个顶点出发,逐步选择与当前已构建的生成树相连接的边中权重最小的边加入生成树中,直到生成...
对于POJ第1861题,参赛者可能需要读取输入数据,构建一个加权图,然后应用Prim或Kruskal算法找出最小生成树,最后输出树中边的权重总和或者某种特定格式的树结构。解题过程可能涉及到错误处理、边界条件检查以及效率...
在【压缩包子文件的文件名称列表】中,"poj 2485 Highways (最小生成树)"可能是题目提供的样例输入和输出文件,用于检验自己编写的程序是否正确。这些样例通常包含了各种边界情况和特殊案例,以确保算法的鲁棒性。 ...
Prim和Kruskal是两种常见的求解最小生成树的算法。在某些情况下,图可能有唯一的最小生成树,这两个实现可能分别使用了这两种方法。 4. **P3522(slimness_kruskal变式).cpp** - "slimness"通常指的是树的直径或者...
常见的求解最小生成树的算法有Prim算法和Kruskal算法。在这个问题中,由于需要先进行快速排序,Kruskal算法更为合适,因为它依赖于边的排序。Kruskal算法的基本步骤是: 1. 将所有边按权重从小到大排序。 2. 初始化...
常见的求解最小生成树的算法有两种:Prim算法和Kruskal算法。从代码中可以看出,这里采用的是Kruskal算法。 #### Kruskal算法详解 Kruskal算法是一种贪心算法,其核心思想是每次选取权重最小的边加入到生成树中,...
常用的最小生成树算法有两种:Prim算法和Kruskal算法。由于本题中图的边数较多(完全图),选择Prim算法更为合适。Prim算法的基本思想是从一个顶点出发,逐步添加权值最小的边来扩展生成树,直到包含所有顶点为止。 ...
总结来说,这个压缩包提供了一个使用最小生成树算法解决POJ2485题目的实例,它涉及了图论、贪心算法、C++编程和在线编程竞赛实践等多个IT领域的知识点。通过分析和学习这个解题代码,我们可以加深对最小生成树算法的...
* 最小生成树算法:最小生成树算法是指计算图的最小生成树的算法,如 prim、kruskal。 * 拓扑排序:拓扑排序是指计算图的拓扑排序的算法,如 poj1094。 * 二分图的最大匹配:二分图的最大匹配是指计算二分图的最大...
* 最小生成树算法:prim、kruskal、POJ1789、POJ2485、POJ1258、POJ3026 * 拓扑排序:POJ1094 * 串算法:POJ1035、POJ3080、POJ1936 * 哈希表和二分查找等高效查找法:POJ3349、POJ3274、POJ2151、POJ1840、POJ2002...
* 最小生成树算法:例如 Prim、Kruskal,例如 poj1789、poj2485、poj1258、poj3026。 * 拓扑排序:例如 poj1094。 * 二分图的最大匹配:例如 poj3041、poj3020。 * 最大流的增广路算法:例如 poj1459、poj3436。...
- 最小生成树算法:如Prim算法和Kruskal算法,用于找出图中的最小生成树,如`poj1789, poj2485`。 - 拓扑排序:适用于有向无环图,用于确定任务的执行顺序,如`poj1094`。 - 二分图的最大匹配:如匈牙利算法,...
图论算法涉及图的数据结构和基于图的各种操作,如最短路径算法(Dijkstra、Bellman-Ford、Floyd)、最小生成树算法(Prim、Kruskal)。Dijkstra算法用于寻找图中两点间的最短路径,而Bellman-Ford算法可以处理带有负...
#### 最小生成树 Prim算法和Kruskal算法分别基于贪心策略和并查集数据结构,用于在带权图中找到连接所有顶点的最小总权重的树结构。 #### 拓扑排序 适用于有向无环图,帮助分析任务依赖关系,如poj1094所示。 ####...
- **知识点**:最小生成树(MST),一种用于构造连接图中所有顶点且总权重最小的树的算法,如Prim算法或Kruskal算法。 #### 1273 Drainage Ditches - 最大流 - **知识点**:最大流算法,用于解决图中源点到汇点的...
2. **最小生成树**:Prim算法和Kruskal算法是两种常见的构建最小生成树的方法。Prim算法从一个顶点开始逐步添加边,而Kruskal算法则是按边的权重从小到大加入,确保不形成环路。 3. **拓扑排序**:对于有向无环图...
4. **最小生成树**:如果涉及网络的基础设施,可能需要找到最小生成树(例如Kruskal's Algorithm或Prim's Algorithm),以最小化破坏成本。 5. **最短路径算法**:Dijkstra's Algorithm或Floyd-Warshall Algorithm...
6. 最小生成树算法(prim, kruskal)(poj1789, poj2485, poj1258, poj3026) 7. 拓扑排序(poj1094) 8. 串(poj1035, poj3080, poj1936) 9. 哈希表和二分查找等高效查找法(poj3349, poj3274, POJ2151, poj1840, ...