POJ1258 基础最小生成树
本文出自:http://blog.csdn.net/svitter
题意:给出一个数字n代表邻接矩阵的大小,随后给出邻接矩阵的值。输出最小生成树的权值。
题解:
prime算法的基本解法;
1.选择一个点,然后不停的向当中增加权值最小的边,边的一端在已经生成的部分生成树中,还有一端在未生成的生成树中。
2.利用优先队列维护边,将增加的点所包括的边增加到队列中去,随后依照边的权值弹出。
简单理解方法:一个人能够拉非常多人,新被拉进来的人,把能拉的人(有边,且未被訪问)排队,找最好拉的人拉进来,循环。
注意:
1.假设使用priority_queue(二叉堆)+prime算法,时间复杂度为ElogV
2.直接使用邻接矩阵,复杂度为O(n^2)
3.使用STL 优先队列的时候记得定义排序方法;(见代码:14行)
4.记得清空vector数组
Kruskal算法的基本解法:
1.Kruskal算法存的是边。将全部边存起来,然后依照从小到大排序,依次增加两端不再同一集合的边。
2.复杂度为O(ElogE)
3.稀疏图
简单理解方法:几个人抱团,最后在全都拉在一起。
树的特点:边的个数是n-1,所以增加n-1条边就可以停止。
Prime+堆解法——代码:
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#define INF 0xffffff using namespace std; struct Edge
{
int v;
int w;
Edge(int v_, int w_):v(v_), w(w_){}
bool operator < (const Edge &e) const
{
return w > e.w;
}
}; typedef vector <Edge> vedge;
vector <vedge> g(110);
int n; int Prime(vector <vedge> & g)
{
int i, j, k;
vector <int> visit(n);
vector <int> dist(n);
priority_queue <Edge> pq;
for(i = 0; i < n; i++)
{
visit[i] = 0;
dist[i] = INF;
} Edge temp(0, 0); int nOwn = 0;
int nWeight = 0;
pq.push(Edge(0, 0)); while(nOwn < n && !pq.empty())
{
do
{
temp = pq.top();
pq.pop();
}
while(visit[temp.v] == 1 && !pq.empty());
if(visit[temp.v] == 0)
{
nOwn++;
nWeight += temp.w;
visit[temp.v] = 1;
}
for(i = 0 ; i < g[temp.v].size(); i++)
{
int v = g[temp.v][i].v;
if(visit[v] == 0)
{
int w = g[temp.v][i].w;
dist[v] = w;
pq.push(Edge(v, w));
}
}
}
if(nOwn < n)
{
cout << nOwn << n << endl;
return -1;
}
return nWeight;
} int main()
{
int i, j, k;
int temp;
while(~scanf("%d", &n))
{
for(i = 0; i < n; i++)
g[i].clear();
for(i = 0; i < n; i++)
for(j = 0; j < n; j++)
{
scanf("%d", &temp);
g[i].push_back(Edge(j, temp));
} cout << Prime(g) << endl;
}
return 0;
}
Kruscal算法代码:
//author: svtter
// #include <algorithm>
#include <vector>
#include <iostream>
#include <stdio.h>
#include <string.h> const int MAXN = 100000; using namespace std; vector <int> root;
int n;
struct Edge
{
int i, j, w;
Edge(int i_, int j_, int w_):i(i_), j(j_), w(w_){}
bool operator < (const Edge &e) const
{
return w < e.w;
}
}; void init()
{
for(int i = 0; i < n; i++)
root.push_back(i);
} int getRoot(int i)
{
if(root[i] == i)
return i;
return root[i] = getRoot(root[i]);
} void Merge(int i, int j)
{
int a, b;
a = getRoot(i);
b = getRoot(j);
if(a == b)
return;
//a's root is a;
root[a] = b;
} vector <Edge> g; int Kruskal()
{
//init the
init();
sort(g.begin(),g.end());
//the num of tree's Edges is n-1;
//
int nEdge = 0; //the weight of whole gtree
int nWeight = 0;
int i, s, e, w;
for(i = 0; i < g.size(); i++)
{
s = g[i].i;
e = g[i].j;
w = g[i].w;
if(getRoot(s) != getRoot(e))
{
Merge(s,e);
nWeight += w;
nEdge++;
}
if(nEdge == n-1)
break;
}
return nWeight;
} int main()
{
int i, j, k;
while(~scanf("%d", &n))
{
g.clear();
root.clear();
for(i = 0; i < n ; i++)
for(j = 0; j < n; j++)
{
scanf("%d", &k);
g.push_back(Edge(i, j, k));
} cout << Kruskal() << endl;
}
return 0;
}
POJ1258 基础最小生成树的更多相关文章
- POJ1258 (最小生成树prim)
Agri-Net Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 46319 Accepted: 19052 Descri ...
- hdu1102 Constructing Roads 基础最小生成树
//克鲁斯卡尔(最小生成树) #include<cstdio> #include<iostream> #include<algorithm> using names ...
- poj1258 Agri-Net 最小生成树
Agri-Net Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 44032 Accepted: 18001 Descri ...
- hdu1162 Eddy's picture 基础最小生成树
#include <cstdio> #include <cmath> #include <cstring> #include <algorithm> # ...
- hdu1301 Jungle Roads 基础最小生成树
#include<iostream> #include<algorithm> using namespace std; ; int n, m; ]; struct node { ...
- hdu1879 继续畅通工程 基础最小生成树
#include <cstdio> #include <cstdlib> #include <algorithm> #include <cmath> u ...
- hdu1875 畅通工程再续 暴力+基础最小生成树
#include<cstdio> #include<cmath> #include<algorithm> using namespace std; ; ; ; in ...
- hdu1863 畅通工程 基础最小生成树
#include <iostream> #include <cstdio> #include <algorithm> #define N 110 #define M ...
- hdu1233 还是畅通工程 基础最小生成树
//克鲁斯卡尔 #include<iostream> #include<algorithm> using namespace std; ; struct node { int ...
随机推荐
- 求Sn=a+aa+aaa+…+aa…aaa(有n个a)…
时间限制: 1 Sec 内存限制: 128 MB 提交: 352 解决: 174 [提交][状态][讨论版] 题目描述 求Sn=a+aa+aaa+-+aa-aaa(有n个a)之值,其中a是一个数字 ...
- x264 - open gop and closed gop
GOP - Group of picture(影像集团),它指的是两个I帧之间的距离. Reference(基准期). 它指的是两个P帧之间的距离. 简而言之, 跨参考gop的,变open gop: ...
- Java重写round()方法
题目:完毕这种方法的代码实现 public static String round (String arg1, int arg2) 參数 arg1:表示等待被处理的数据:如:"100.286 ...
- NuttX 介绍
(嵌入式 实时操作系统 rtos nuttx 7.1) NuttX 介绍 转载请注明出处:http://blog.csdn.net/zhumaill/article/details/24197637 ...
- HDU 1176 免费馅饼(DP)
职务地址:HDU 1176 以时间为横轴.11个点位纵轴构造一个矩阵.然后利用数字三角形的方法从上往下递推下去. 代码例如以下: #include <iostream> #include ...
- outlook 当关闭时最小化到任务栏完美的解决方案
近期使用Outlook,但很发现easy退出关闭.不能达到最小化封. 在网上找了很长时间也用outlook on the desktop插件,但该插件安装后的执行错误和被遗弃. 最后,我发现了一个叫k ...
- 自己的自定义单元格(IOS)
定义自己的单位格有三种方法 - 代码 - xib - storyboard(推荐) 操作方法故事板 1.在TableView财产Prototype Cells至1.莫感觉1: 2.须要创建自己定义的单 ...
- 上传文件块client实现
首先由内容阻止所有文件(块大小的约束),然后对于每一个chunk构造单独的一个UDP 数据报进行传输,在应用层的開始是自己定义的包头,有块号,块长度,块指纹等元数据信息,这些信息便于接收端可以按序正确 ...
- OpenGL于MFC使用汇总(三)——离屏渲染
有时直接创建OpenGL形式不适合,或者干脆不同意然后创建一个表单,正如我现在这个项目,创建窗体不显示,它仅限于主框架.而我只是ActiveX里做一些相关工作,那仅仅能用到OpenGL的离屏渲染技术了 ...
- CSS3实现Tooltip提示框飞入飞出动画
原文:CSS3实现Tooltip提示框飞入飞出动画 我们见过很多利用背景图片制作的Tooltip提示框,但是缺点是扩展比较麻烦,要经常改动图片.还有就是利用多层CSS的叠加实现,但是效果比较生硬,外观 ...