poj1861 最小生成树 prim & kruskal

来源:互联网 发布:mac如何切换大小写 编辑:程序博客网 时间:2024/06/05 12:38
//    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();    }}


0 0
原创粉丝点击