• HDU 1102 最小生成树裸题,kruskal,prim


    1、HDU  1102  Constructing Roads    最小生成树

    2、总结:

    题意:修路,裸题

    (1)kruskal

    //kruskal
    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    #include<cstdio>
    #define max(a,b) a>b?a:b
    using namespace std;
    #define LL long long
    #define INF 0x3f3f3f3f
    const int N=110;
    
    int n,k;
    int father[N];
    
    struct Eage
    {
        int st,en,val;
    }eage[N*(N+1)/2];
    
    bool cmp(Eage a,Eage b)
    {
        return a.val<b.val;
    }
    
    int findn(int x)   //即并查集的查找
    {
        int t=x;
        while(x!=father[x]){
            x=father[x];
        }
        int p;
        while(t!=x){
            p=t;
            t=father[t];
            father[p]=x;
        }
        return x;
    }
    
    int kruskal()
    {
        int sum=0;
        sort(eage,eage+k,cmp);
        for(int i=0;i<k;i++){
            int x=findn(eage[i].st);
            int y=findn(eage[i].en);
            if(x!=y){
                sum+=eage[i].val;
                x=findn(x);
                y=findn(y);
                father[x]=y;
            }
        }
        return sum;
    }
    
    int main()
    {
        while(scanf("%d",&n)!=EOF)
        {
            int m;
            k=0;
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    scanf("%d",&m);
                    if(i<j){
                        eage[k].st=i;   //st边起点,en边终点,k为边的条数
                        eage[k].en=j;
                        eage[k++].val=m;
                    }
                }
            }
    
            for(int i=1;i<=n;i++){
                father[i]=i;
            }
            int q,a,b;
            scanf("%d",&q);
            while(q--){
                scanf("%d%d",&a,&b);
                a=findn(a);
                b=findn(b);
                father[a]=findn(b);  //把a与b连通
            }
    
            int ans=kruskal();
            printf("%d
    ",ans);
        }
    
        return 0;
    }
    View Code

    (2)prim

    //prim
    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    #include<cstdio>
    #define max(a,b) a>b?a:b
    using namespace std;
    #define LL long long
    #define INF 0x3f3f3f3f
    const int N=110;
    
    int n;
    int mapn[N][N];
    int visit[N],dis[N];   //dis存储每个点到所选结点的最短距离
    
    int prim()
    {
        int sum=0;
        memset(visit,0,sizeof(visit));
        visit[1]=1;
        for(int i=1;i<=n;i++){  //先选第一个结点
            dis[i]=mapn[1][i];
        }
        for(int i=1;i<n;i++)    //注,<不是<=
        {
            int next,minn=INF;
            for(int j=1;j<=n;j++){  //找到下一个最近的结点
                if(!visit[j]&&minn>dis[j]){
                    next=j;
                    minn=dis[j];
                }
            }
            sum+=minn;
            visit[next]=1;
    
            for(int j=1;j<=n;j++){  //更新dis
                if(!visit[j]&&dis[j]>mapn[next][j]){
                    dis[j]=mapn[next][j];
                }
            }
        }
        return sum;
    }
    
    int main()
    {
        int q,a,b;
        while(scanf("%d",&n)!=EOF)
        {
            memset(mapn,INF,sizeof(mapn));
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    scanf("%d",&mapn[i][j]);
                }
            }
    
            scanf("%d",&q);
            while(q--){
                scanf("%d%d",&a,&b);
                mapn[a][b]=mapn[b][a]=0;
            }
    
            int ans=prim();
            printf("%d
    ",ans);
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    【Git】rebase 用法小结(转)
    修饰符访问权限。
    throws与throw关键字。
    多线程,同步代码块。
    多线程,设置线程的优先级。
    多线程,加入线程。
    多线程,守护线程。
    多线程,休眠线程。
    多线程,获取当前线程的对象。
    多线程获取名字和设置名字。
  • 原文地址:https://www.cnblogs.com/sbfhy/p/5814120.html
Copyright © 2020-2023  润新知