// poj1861 最小生成树 prim & kruskal
//
// 一个水题,为的只是回味一下模板,日后好有个照应不是
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <iostream>
using namespace std;
const int MAX_N = 1008;
const int INF = 0x3f3f3f3f;
int g[MAX_N][MAX_N];
int n,m;
int cnt;
int mx;
int d[MAX_N];
bool vis[MAX_N];
int pre[MAX_N];
struct edge{
int from;
int to;
int w;
edge(){
}
edge(int from,int to,int w): from(from),to(to),w(w){
}
};
edge edges[MAX_N * 15];
bool cmp(edge a,edge b){
return a.w < b.w;
}
void print1(){
for (int i=1;i<=n;i++){
for (int j=1;j<=n;j++)
printf("%d ",g[i][j]);
puts("");
}
}
void input1(){
int u,v,cost;
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++){
g[i][j] = INF;
if (i == j)
g[i][j] = 0;
}
for (int i=0;i<m;i++){
scanf("%d%d%d",&u,&v,&cost);
g[u][v] = g[v][u] = cost;
}
// print1();
for (int i=1;i<=n;i++){
pre[i] = 1;
}
cnt = 0;
}
int fa[MAX_N];
int height[MAX_N];
void input2(){
int u,v,cost;
for (int i=1;i<=m;i++){
scanf("%d%d%d",&u,&v,&cost);
edges[i] = edge(u,v,cost);
}
for (int i=1;i<=n;i++){
fa[i] = i;
height[i] = 0;
}
sort(edges+1,edges+m+1,cmp);
}
int getf(int x){
if (x==fa[x])
return x;
return fa[x] = getf(fa[x]);
}
void kruskal(){
int cnt = 0;
int mx = 0;
for (int i=1;i<=m;i++){
int x = getf(edges[i].from);
int y = getf(edges[i].to);
if (x==y)
continue;
if (height[x] < height[y]){
fa[x] = y;
}else {
fa[y] = x;
if (height[x]==height[y])
height[x]++;
}
mx = max(mx,edges[i].w);
edges[cnt++] = edges[i];
}
printf("%d\n",mx);
printf("%d\n",cnt);
for (int i=0;i<cnt;i++){
printf("%d %d\n",edges[i].from,edges[i].to);
}
}
void prim(){
for (int i=1;i<=n;i++)
d[i] = g[1][i];
d[1] = 0;
for (int i=1;i<=n;i++){
vis[i] = 0;
}
vis[1] = 1;
mx = 0;
for (int i=1;i<=n;i++){
int k = -1;
for (int j=1;j<=n;j++){
if (!vis[j] && (k == -1 || d[k] > d[j])){
k = j;
}
}
if (k==-1)
break;
vis[k]++;
mx = max(mx,d[k]);
edges[cnt++] = edge(k,pre[k],d[k]);
for (int j=1;j<=n;j++){
if (!vis[j] && g[k][j]!= INF &&d[j] > g[k][j]){
d[j] = g[k][j];
pre[j] = k;
}
}
}
}
void print(){
printf("%d\n",mx);
printf("%d\n",cnt);
for (int i=0;i<cnt;i++){
printf("%d %d\n",edges[i].from,edges[i].to);
}
}
void solve(){
//prim();
kruskal();
//print();
}
int main(){
freopen("1.txt","r",stdin);
while(scanf("%d%d",&n,&m)!=EOF){
//input1();
input2();
solve();
}
}
poj1861 最小生成树 prim & kruskal
最新推荐文章于 2019-07-26 22:51:39 发布