• hdu1233


    还是畅通工程

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 20659    Accepted Submission(s): 9180


    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
     
    代码:(并查集)
    #include<stdio.h>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    int n,sum;
    int father[110];
    void make_set()
    {
        int i;
        for(i=1; i<=n; i++)
            father[i]=i;
    }
    int find_set(int x)
    {
        return x==father[x]?x:father[x]=find_set(father[x]);
    }
    struct edg
    {
        int start,end,dis;
    } a[5100];
    int cmp(edg a,edg b)
    {
        return a.dis<b.dis;
    }
    void unon(int x,int y,int z)
    {
        x=find_set(x);
        y=find_set(y);
        if(x!=y)
        {
            sum+=z;
        father[y]=x;
        }
    }
    int main()
    {
        int m,i,j;
        while(~scanf("%d",&n)&&n)
        {
            sum=0;
            make_set();
            m=n*(n-1)/2;
            for(i=1; i<=m; i++)
                scanf("%d%d%d",&a[i].start,&a[i].end,&a[i].dis);
            sort(a+1,a+m+1,cmp);//道路的值按照从小到大排序
            for(i=1; i<=m; i++)
                unon(a[i].start,a[i].end,a[i].dis);
            printf("%d
    ",sum);
        }
    }
    代码:(prim算法实现)
    #include<stdio.h>
    #include<string.h>
    #define MAX 0x3f3f3f3
    //创建map二维数组储存图表,low数组记录每2个点间最小权值,visited数组标记某点是否已访问
    int map[1000][1000],low[1100],visit[1100],n;
    int prim()
    {
     int i,pos,min,sum=0,j;
     memset(visit,0,sizeof(visit));
    //从某点开始,分别标记和记录该点
     visit[1]=1;
     pos=1;
    //第一次给low数组赋值
     for(i=1;i<=n;i++)
      if(i!=pos)
      low[i]=map[pos][i];
    //再运行n-1次 
     for(i=1;i<n;i++)
     {
    //找出最小权值并记录位置
      min=MAX;
      for(j=1;j<=n;j++)
      {
       if(visit[j]==0&&min>low[j])
       {
        min=low[j];
        pos=j;
       }
      }
    //最小权值累加
           sum+=min;
    //标记该点
        visit[pos]=1;
    //更新权值
        for(j=1;j<=n;j++)
        {
         if(visit[j]==0&&low[j]>map[pos][j])
          low[j]=map[pos][j];
        }
     }
     return sum; 
    }
    int main()
    {
       int m,j,i,a,b,c;
       while(~scanf("%d",&n)&&n)
       {
        m=n*(n-1)/2;
    //所有权值初始化为最大
        memset(map,MAX,sizeof(map));
        for(i=1;i<=m;i++)
        {
         scanf("%d%d%d",&a,&b,&c);
         map[a][b]=map[b][a]=c;
        }
        printf("%d ",prim());
       }
    }
  • 相关阅读:
    《复杂网络环境下访问控制技术》读书笔记(2)
    《复杂网络环境下访问控制技术》读书笔记(1)
    20199319《网络攻防实践》假期作业
    云班课实验补充
    20199319 缓冲区溢出漏洞试验
    20199319《Linux内核原理与分析》第十二周作业
    20199319《Linux内核原理与分析》第十一周作业
    图书管理系统UML建模
    《深入理解计算机系统(第三版)》第二章学习总结
    2019-2020-1 20199319《Linux内核原理与分析》第九周作业
  • 原文地址:https://www.cnblogs.com/lxm940130740/p/3276284.html
Copyright © 2020-2023  润新知