poj 2485 简单的最小生…
2013-12-14 20:03
447 查看
题目意思:要你求一个生成树 , 使这个生成树(不一定是最小生成树)中边权最大值最小 , 并输出该值。
这个题目我一开始用的是kruskal算法 , 先对边进行排序 , 但后面犯了一个错误 , 当判断是否存在生成树时 ,
我判断的是前面的边是否包含所有顶点(没有发现 , 有可能这些点不是在通一个连通图中) , 应该用并查集 。
其实最大值最小就是最小生成树中的最大值 , 这个性质的证明可以用kruskal算法来证明:
1、对边排序后 , 我们取前n-1条边 , 如果这n-1条边 , 构成了最小生成树 ,
那么该值就是它们之间的最大值 。
2、如果不能构成生成树 , 那么继续加入下一条边(除开已取的边之外 , 取剩下边的最小值) ,
因为前面那些边不能构成生成树 , 那么如果加入这条边之后 , 可以构成生成树 , 则这条边肯定在该生成树中 ,
并且这条边的权值就是我们要求的值 。
3、如果加入该边后还不能构成最小生成树 , 那么重复步骤2
, 直到可以形成生成树为止。
代码:
#include
#include
#include
using namespace std;
const int MAXN = 550 ;
int grap[MAXN][MAXN] , u[630000] , v[630000] , d[630000] ;
int done[630000] , n , f[MAXN];
bool cmp(int i , int j)
{
return d[i]
< d[j];
}
int find(int x)
{
int u =
x;
while(x !=
f[x])
{
x =
f[x];
}
while(u !=
x)
{
int p =
f[u];
f[u] =
x;
u = p;
}
return
x;
}
int main()
{
int t;
scanf("%d" ,
&t);
while(t--)
{
int i ,
j;
cin>>n;
for(i = 1; i
<= n; i++)
{
for(j = 1; j
<= n; j++)
scanf("%d" ,
&grap[i][j]);
f[i] =
i;
}
int x =
0;
for(i = 1; i
<= n; i++)
{
for(j = i+1;
j <= n; j++)
{
u[x] =
i; v[x] = j;
d[x] =
grap[i][j];
done[x] =
x;
x +=
1;
}
}
int c , g ,
h;
sort(done ,
done+x , cmp);
这个题目我一开始用的是kruskal算法 , 先对边进行排序 , 但后面犯了一个错误 , 当判断是否存在生成树时 ,
我判断的是前面的边是否包含所有顶点(没有发现 , 有可能这些点不是在通一个连通图中) , 应该用并查集 。
其实最大值最小就是最小生成树中的最大值 , 这个性质的证明可以用kruskal算法来证明:
1、对边排序后 , 我们取前n-1条边 , 如果这n-1条边 , 构成了最小生成树 ,
那么该值就是它们之间的最大值 。
2、如果不能构成生成树 , 那么继续加入下一条边(除开已取的边之外 , 取剩下边的最小值) ,
因为前面那些边不能构成生成树 , 那么如果加入这条边之后 , 可以构成生成树 , 则这条边肯定在该生成树中 ,
并且这条边的权值就是我们要求的值 。
3、如果加入该边后还不能构成最小生成树 , 那么重复步骤2
, 直到可以形成生成树为止。
代码:
#include
#include
#include
using namespace std;
const int MAXN = 550 ;
int grap[MAXN][MAXN] , u[630000] , v[630000] , d[630000] ;
int done[630000] , n , f[MAXN];
bool cmp(int i , int j)
{
return d[i]
< d[j];
}
int find(int x)
{
int u =
x;
while(x !=
f[x])
{
x =
f[x];
}
while(u !=
x)
{
int p =
f[u];
f[u] =
x;
u = p;
}
return
x;
}
int main()
{
int t;
scanf("%d" ,
&t);
while(t--)
{
int i ,
j;
cin>>n;
for(i = 1; i
<= n; i++)
{
for(j = 1; j
<= n; j++)
scanf("%d" ,
&grap[i][j]);
f[i] =
i;
}
int x =
0;
for(i = 1; i
<= n; i++)
{
for(j = i+1;
j <= n; j++)
{
u[x] =
i; v[x] = j;
d[x] =
grap[i][j];
done[x] =
x;
x +=
1;
}
}
int c , g ,
h;
sort(done ,
done+x , cmp);
相关文章推荐
- 我的博客今天0岁42天了,我领取了…
- LA 4080 Warfare A…
- hdu 2433 最短路树
- 【快速】排序, T(n) = O(nlgn),O(n^2) S(n) = O(lgn) --- 不稳定
- (C# 基础) 类访问修饰符
- LA 3713 Astronauts
- LA 3211 Now or later
- uva 11324
- LA 5135 Mining Your Own Business
- http://kb.cnblogs.com/page/130970/ -http协议
- poj 2942 LA3523 点-双…
- uva 10047
- STL中优先队列的用法
- 并查集及其路径的压缩
- 求欧拉回路的路径 dfs的一种新运用
- poj 2676
- poj 2531
- poj 2251
- poj 2488
- 网络流 SAP优化算法 (…