POJ 1861题
2010-04-30 22:26
176 查看
//最小生成树:Kruskal算法
#include <stdio.h>
#include <algorithm>
using namespace std;
#define arraysize 15001
#define nodenum 1001
typedef struct node
{
int start; //起点
int end; //终点
int w; //费用
};
node edges[arraysize]; //存储边
node record[arraysize]; //存储最小生成树中的边
int final[nodenum]; //存储该点的双亲节点
int r[nodenum]; //存储以nodenum为根的树的节点数(包括根)
bool cmp(node a,node b)
{
return a.w<b.w;
}
int findroot(int n) //找到n的根节点
{
if(final
== n)
return n;
else
{
final
= findroot(final
);
}
return final
;
}
int main()
{
//freopen("1.txt","r",stdin);
int N,M;
while(scanf("%d%d",&N,&M)!=EOF)
{
int start,end,w;
for(int i=1;i<M+1;++i)
{
scanf("%d%d%d",&start,&end,&w);
edges[i].start = start;
edges[i].end = end;
edges[i].w = w;
}
//Kruskal算法,初始化,建立n棵树
for(int i1=1;i1<N+1;i1++)
{
final[i1] = i1;
r[i1] = 1;
}
//对边进行排序
sort(edges+1,edges+M+1,cmp); //此处第一个参数是edges+1,第二个参数是edges+M+1
int flag = 0; //记录最小生成树中的边数
int maxLength = 0; //记录最小生成树种的最大边
//遍历所有的边
for(int i2=1;i2<M+1;++i2)
{
int a = edges[i2].start;
int b = edges[i2].end;
int w = edges[i2].w;
//查找边的源点的根节点
int roota = findroot(a);
//查找边的终点的根节点
int rootb = findroot(b);
//如果边的源点和边的终点不在同一连通子图中,则将该点加入到最小生成树中
if(roota != rootb)
{
flag++;
record[flag].start = a;
record[flag].end = b;
record[flag].w = w;
if(record[flag].w>maxLength)
{
maxLength = record[flag].w;
}
if(r[roota]>=r[rootb])
{
final[rootb] = a;
r[roota] += r[rootb];
}
else
{
final[roota] = b;
r[rootb] += r[roota];
}
}
if(flag == N-1) //找到了最小生成树
{
printf("%d\n%d\n",maxLength,flag);
for(int j=1;j<=flag;++j)
{
printf("%d %d\n",record[j].start,record[j].end);
}
break;
}
}
}
return 0;
}
#include <stdio.h>
#include <algorithm>
using namespace std;
#define arraysize 15001
#define nodenum 1001
typedef struct node
{
int start; //起点
int end; //终点
int w; //费用
};
node edges[arraysize]; //存储边
node record[arraysize]; //存储最小生成树中的边
int final[nodenum]; //存储该点的双亲节点
int r[nodenum]; //存储以nodenum为根的树的节点数(包括根)
bool cmp(node a,node b)
{
return a.w<b.w;
}
int findroot(int n) //找到n的根节点
{
if(final
== n)
return n;
else
{
final
= findroot(final
);
}
return final
;
}
int main()
{
//freopen("1.txt","r",stdin);
int N,M;
while(scanf("%d%d",&N,&M)!=EOF)
{
int start,end,w;
for(int i=1;i<M+1;++i)
{
scanf("%d%d%d",&start,&end,&w);
edges[i].start = start;
edges[i].end = end;
edges[i].w = w;
}
//Kruskal算法,初始化,建立n棵树
for(int i1=1;i1<N+1;i1++)
{
final[i1] = i1;
r[i1] = 1;
}
//对边进行排序
sort(edges+1,edges+M+1,cmp); //此处第一个参数是edges+1,第二个参数是edges+M+1
int flag = 0; //记录最小生成树中的边数
int maxLength = 0; //记录最小生成树种的最大边
//遍历所有的边
for(int i2=1;i2<M+1;++i2)
{
int a = edges[i2].start;
int b = edges[i2].end;
int w = edges[i2].w;
//查找边的源点的根节点
int roota = findroot(a);
//查找边的终点的根节点
int rootb = findroot(b);
//如果边的源点和边的终点不在同一连通子图中,则将该点加入到最小生成树中
if(roota != rootb)
{
flag++;
record[flag].start = a;
record[flag].end = b;
record[flag].w = w;
if(record[flag].w>maxLength)
{
maxLength = record[flag].w;
}
if(r[roota]>=r[rootb])
{
final[rootb] = a;
r[roota] += r[rootb];
}
else
{
final[roota] = b;
r[rootb] += r[roota];
}
}
if(flag == N-1) //找到了最小生成树
{
printf("%d\n%d\n",maxLength,flag);
for(int j=1;j<=flag;++j)
{
printf("%d %d\n",record[j].start,record[j].end);
}
break;
}
}
}
return 0;
}
相关文章推荐
- POJ 1861
- POJ 1861 Network [最小生成树算法MST-kruskal 数据结构-并查集 union-find sets]
- poj 1861 Network
- poj 1861 Network
- POJ-1861-Network
- (kruscal12.3.1)POJ 1861 Network(求最小生成树的最大边&&并且输出各边的信息)
- poj-1861-MST
- poj 1861 并查集+kruskal 解题报告
- poj 1861 Networks
- poj 1861 network
- POJ 1861
- POJ 1861 Network (MST)
- poj 1861 Network
- POJ 1861 Network
- POJ 1861 Network(求连接的边) 水题
- poj 1861
- poj1861解题报告
- POJ 1861 Network (Kruskal算法+输出的最小生成树里最长的边==最后加入生成树的边权 *【模板】)
- poj 1861 Network MST
- ZOJ 1542 poj 1861 Network(并查集+最小树)