最小生成树水题……全部用kruskal模板编写。(结合并查集)
POJ2377
注意kruskal的各个步骤
注意使用时对模板的修改
/*kruskal
**并查集实现
**1.边权值排序sort
**2.选择最小的边
**3.判断最小边上的点是否同一集合
**不是同一集合就合并
*/
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
#define MAX 1002
struct edge{
int u,v,cost;
};
vector<edge> G;
int V,E;
int rank[MAX],par[MAX];
void init(int n){
for(int i=0;i<n;i++){
rank[i]=0;
par[i]=i;
}
return ;
}
int find(int x){
if(par[x]==x) return x;
else return par[x]=find(par[x]);
}
bool same(int x,int y){
return find(x)==find(y);
}
void unit(int x,int y){
x=find(x);
y=find(y);
if(x==y) return;
if(rank[x]<rank[y]){
par[x]=y;
}else{
par[y]=x;
if(rank[x]==rank[y]) rank[x]++;
}
}
bool mycom(const edge &e1,const edge &e2){
return e1.cost>e2.cost;
}
int main(){
scanf("%d%d",&V,&E);
init(V);
edge ed;
for(int i=0;i<E;i++){
scanf("%d %d %d",&ed.u,&ed.v,&ed.cost);
G.push_back(ed);
}
sort(G.begin(),G.end(),mycom);
int res=0;
int temp=1;
for(int i=0;i<E;i++){
if(!same( G[i].u, G[i].v ) ){
unit(G[i].u,G[i].v);
res+=G[i].cost;
temp++;
}
}
if(temp!=V){
puts("-1");
}else
printf("%d\n",res);
return 0;
}
POJ1258
处理输入格式,由于是无向图,只需要获得上三角或者下三角的数据即可
然后存进来,用kruskal
不过这道题边比较多,感觉更适合用prim,但是kruskal也能做的嘛~
他俩时间复杂度都是o(E logV)
/*kruskal
**并查集实现
**1.边权值排序sort
**2.选择最小的边
**3.判断最小边上的点是否同一集合
**不是同一集合就合并
*/
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
#define MAX 110
struct edge{
int u,v,cost;
}G[5000];
edge ed;
int V,E;
int rank[MAX],par[MAX];
void init(int n){
for(int i=0;i<n;i++){
rank[i]=0;
par[i]=i;
}
return ;
}
int find(int x){
if(par[x]==x) return x;
else return par[x]=find(par[x]);
}
bool same(int x,int y){
return find(x)==find(y);
}
void unit(int x,int y){
x=find(x);
y=find(y);
if(x==y) return;
if(rank[x]<rank[y]){
par[x]=y;
}else{
par[y]=x;
if(rank[x]==rank[y]) rank[x]++;
}
}
bool mycom(const edge &e1,const edge &e2){
return e1.cost<e2.cost;
}
int main(){
int n;
while(scanf("%d",&n)!=EOF){
int t,k=0;
for(int i=0;i<n;i++){a
for(int j=0;j<n;j++){
scanf("%d",&t);
if(i<j){
ed.u=i,ed.v=j,ed.cost=t;
G[k++]=ed;
}
}
}
init(n);
sort(G,G+k,mycom);
int res=0;
for(int i=0;i<k;i++){
if(!same( G[i].u, G[i].v ) ){
unit(G[i].u,G[i].v);
res+=G[i].cost;
}
}
printf("%d\n",res);
}
return 0;
}
poj2358
根据题意实际上就是求最小生成树中的最长边。
kruskal是先排序然后依次加入边,(前提是这个边不会构成环),所以每次都是保存最小生成树中最后加入的边
所以最后插入的边就是答案。
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
#define MAX 2002
struct edge{
int u,v,cost;
};
vector<edge> G;
int V,E;
int rank[MAX],par[MAX];
void init(int n){
for(int i=0;i<n;i++){
rank[i]=0;
par[i]=i;
}
return ;
}
int find(int x){
if(par[x]==x) return x;
else return par[x]=find(par[x]);
}
bool same(int x,int y){
return find(x)==find(y);
}
void unit(int x,int y){
x=find(x);
y=find(y);
if(x==y) return;
if(rank[x]<rank[y]){
par[x]=y;
}else{
par[y]=x;
if(rank[x]==rank[y]) rank[x]++;
}
}
bool mycom(const edge &e1,const edge &e2){
return e1.cost<e2.cost;
}
int main(){
scanf("%d%d",&V,&E);
init(V);
edge ed;
for(int i=0;i<E;i++){
scanf("%d %d %d",&ed.u,&ed.v,&ed.cost);
G.push_back(ed);
}
sort(G.begin(),G.end(),mycom);
int res=G[0].cost;
int temp=1;
for(int i=0;i<E;i++){
if(!same( G[i].u, G[i].v ) ){
unit(G[i].u,G[i].v);
res=G[i].cost;
}
}
printf("%d\n",res);
return 0;
}
hdu1233
畅通工程
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
#define MAX 102
struct edge{
int u,v,cost;
};
vector<edge> G;
int ran[MAX],par[MAX];
int V,E;
/*并查集*/
void init(int n){
for(int i=0;i<=n;i++){
ran[i]=0;
par[i]=i;
}
}
int find(int x){
if(x==par[x]) return x;
else return par[x]=find(par[x]);
}
bool same(int x,int y){
return find(x)==find(y);
}
void unit(int x,int y){
x=find(x),y=find(y);
if(x==y) return ;
if(ran[x]<ran[y]){
par[x]=y;
}
else{
par[y]=x;
if(ran[x]==ran[y])
ran[x]++;
}
}
bool mycom(const edge &e1,const edge &e2){
return e1.cost<e2.cost;
}
int main(){
edge ed;
while(scanf("%d",&V)!=EOF&&V!=0){
G.clear();
E=V*(V-1)/2;
for(int i=0; i<E; i++){
scanf("%d%d%d",&ed.u,&ed.v,&ed.cost);
G.push_back(ed);
}
sort(G.begin(),G.end(),mycom);
init(V);
int res=0;
for(int i=0;i<G.size();i++){
if(!same(G[i].u,G[i].v)){
unit(G[i].u,G[i].v);
res+=G[i].cost;
}
}
printf("%d\n",res);
}
return 0;
}