poj1861 最小生成树 prim & kruskal
Posted lxjshuju
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj1861 最小生成树 prim & kruskal相关的知识,希望对你有一定的参考价值。
// 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的主要内容,如果未能解决你的问题,请参考以下文章
ZOJ 1542 POJ 1861 Network 网络 最小生成树,求最长边,Kruskal算法