• HDU1233 还是畅通工程(模版题(prim+kruskal)两种模版)


    Problem Description
    某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。
    Input
    测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1到N编号。
    当N为0时,输入结束,该用例不被处理。
    Output
    对每个测试用例,在1行里输出最小的公路总长度。
    Sample Input
    3
    1 2 1
    1 3 2
    2 3 4
    4
    1 2 1
    1 3 4
    1 4 1
    2 3 3
    2 4 2
    3 4 5
    0
    Sample Output
    3 5
    Hint
    Huge input, scanf is recommended.
    prim模版:
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <queue>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    #define inf 10000000
    #define M 5000
    int n,a,b,d,s[M][M],dis[M];
    bool vis[M];
    void prim()
    {
        vis[0]=true;
        for(int i=1; i<n; i++)
            dis[i]=s[0][i];
        int sum=0,u;
        for(int i=1; i<n; i++)
        {
            int p=inf;
            for(int j=1; j<n; j++)
            {
                if(!vis[j]&&p>dis[j])
                {
                    p=dis[j];
                    u=j;
                }
            }
            vis[u]=true;
            sum+=p;
            for(int j=1; j<n; j++)
                if(!vis[j]&&s[u][j]<dis[j]) dis[j]=s[u][j];
        }
        printf("%d
    ",sum);
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        while(~scanf("%d",&n)&&n)
        {
            int m=n*(n-1)/2;
            for(int i=0;i<m;i++)
            {
                scanf("%d%d%d",&a,&b,&d);
                s[a-1][b-1]=s[b-1][a-1]=d;
            }
            memset(vis,false,sizeof(vis));
            prim();
        }
        return 0;
    }

     kruskal模版:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <queue>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    #define M 105
    struct wq
    {
        int a,b,w;
    }s[M*M];
    int n,m,pre[M];
    bool cmp(wq a,wq b)
    {
        return a.w<b.w;
    }
    int Find(int x)
    {
        int r=x;
        while(r!=pre[r])
            r=pre[r];
        int i=x,j;
        while(i!=r)
        {
            j=pre[i];
            pre[i]=r;
            i=j;
        }
        return r;
    }
    void solve()
    {
        int ans=0,cnt=0;
        sort(s+1,s+m+1,cmp);
        for(int i=1;i<=n;i++)
            pre[i]=i;
        for(int i=1;i<=m;i++)
        {
            int fa=Find(s[i].a);
            int fb=Find(s[i].b);
            if(fa!=fb)
            {
                pre[fa]=fb;
                ans+=s[i].w;
                cnt++;
                if(cnt==n-1) break;
            }
        }
        printf("%d
    ",ans);
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        while(~scanf("%d",&n)&&n)
        {
            m=n*(n-1)/2;
            for(int i=1;i<=m;i++)
                scanf("%d%d%d",&s[i].a,&s[i].b,&s[i].w);
            solve();
        }
        return 0;
    }
  • 相关阅读:
    记一次阿里云硬盘在线扩容
    大文件传输技巧-----split切割
    数据库迁移-------通过ibdata1文件和数据库文件迁移
    小技巧---------------vim 使用技巧 set paste 解决粘贴乱序问题
    webfrom 做项目的注意事项
    webform 复合控件
    wenfrom的简单控件和repeater控件
    分页功能 与 分类查询功能合并
    内置对象2
    简单的人员管理系统
  • 原文地址:https://www.cnblogs.com/d-e-v-i-l/p/4752120.html
Copyright © 2020-2023  润新知