引水工程 Kruskal + Prim

Kruskal题解 : 以案例输入为例 有五个缺水地区 , 这个个缺水地区之间建立联系的费用已经给出 并且之间水库的费用也已经给出 , 自己水库也已看为 是另一个 点 , 这样就有了 6 个点 , 这六个点彼此之间可以建立联系 , 总共形成 5 条边 , 将这 6 个点连接起来 , 这样就符合了题意 , 也可以更好的 用Kruskal 解决 这一个问题 ,  我们可以让  这五个点 建立一个 到 0 的 距离关系 , 这样就有 0 - 6 六个点了 , 下面附上 实现代码

从水库和各个点之间的通道是单向的 ,

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<math.h>
 4 #include<iostream>
 5 #include<limits.h>
 6 #include<algorithm>
 7 #include<queue>
 8 #include<vector>
 9 #include<set>
10 #include<stack>
11 #include<string>
12 #include<sstream>
13 #include<map>
14 #include<cctype>
15 using namespace std;
16 int n,m,minn,father[305],sum,tem[305];
17 struct node
18 {
19     int x,y,l;
20 }a[90005];
21 bool cmp(node a,node b)
22 {
23     return a.l<b.l;
24 }
25 int find(int x)                      //  做了时间上的优化 ,但是 在空间复杂度上比较高
26 {
27     if(x!=father[x])
28         father[x]=find(father[x]);
29     sum++;
30     return father[x];
31 }
32 bool merge(int x,int y)    // 做了时间复杂度上的优化  让并查集的 深度尽量  浅
33 {
34     int sum1,sum2;
35     sum=0;
36     x=find(x);
37     sum1=sum;        //    x  的深度
38     sum=0;
39     y=find(y);
40     sum2=sum;       //    y   的深度
41     if(x!=y)
42     {
43         if(sum1>sum2)
44             father[y]=x;
45         else
46             father[x]=y;
47         return true;
48     }
49     else
50         return false;
51 }
52 int main()              //  先用  Dijkstra 做一次   // Dijkstra 是 根据边来做的
53 {
54     int t;
55     scanf("%d",&t);
56     while(t--)
57     {
58         scanf("%d",&n);
59         for(int i=0;i<=n;i++)
60             father[i]=i;
61         int q=0;
62         for(int i=0;i<=n;i++)
63         {
64             for(int j=1;j<=n;j++)
65             {
66                 int e;
67                 scanf("%d",&e);
68                 a[q].x=j;
69                 a[q].y=i;
70                 a[q].l=e;
71                 q++;
72             }
73         }
74         int m=n*n,sum3=0,count1=0;
75         sort(a,a+q,cmp);
76         for(int i=0;i<q;i++)
77         {
78             if(merge(a[i].x,a[i].y))
79             {
80                     sum3+=a[i].l;
81                     count1++;
82             }
83             if(count1==n)           //  如果边数等于 所有需要连接的 点数-1的话 就跳出去
84                 break;
85         }
86         printf("%d\n",sum3);
87     }
88     return 0;
89 }

Prim 题解 : Prim 是根据 点之间的关系 去 构成最小生成树的  ,   做题的思路和上面 Kruskal 处理之间水库一样 下面附上实现代码   .

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<math.h>
 4 #include<iostream>
 5 #include<limits.h>
 6 #include<algorithm>
 7 #include<queue>
 8 #include<vector>
 9 #include<set>
10 #include<stack>
11 #include<string>
12 #include<sstream>
13 #include<map>
14 #include<cctype>
15 using namespace std;
16 int a[305][305],visited[305],dis[305];
17 int main()
18 {
19     int t,n;
20     scanf("%d",&t);
21     while(t--)
22     {
23         scanf("%d",&n);
24         for(int i=0;i<=n;i++)
25         {
26             dis[i]=INT_MAX;
27             for(int j=0;j<=n;j++)
28             {
29                 a[i][j]=INT_MAX;
30             }
31         }
32         memset(visited,0,sizeof(visited));
33         for(int i=0;i<=n;i++)
34         {
35             for(int j=1;j<=n;j++)
36             {
37                 scanf("%d",&a[i][j]);  //
38                 if(i==0)
39                     a[j][i]=a[i][j];  //  OK  !
40             }
41         }
42         int n1=n,minn,j,b=0,sum=0;
43         visited[0]=1;  //从水库开始吧
44         while(n1--)  //  一共 n+1 个点 需要 n 个边
45         {
46             minn=INT_MAX;
47             for(int i=0;i<=n;i++)
48             {
49                 if(b!=i&&a[b][i]<dis[i]&&!visited[i])  //       visited  控制 是否成环
50                 {
51                     dis[i]=a[b][i];  //  如果不是自己到自己 并且 现在该点到 以前该点比已经确定的集合的距离短的话 ,那么就刷新距离
52                 }
53             }
54             for(int i=0;i<=n;i++)
55             {
56                 if(minn>dis[i]&&!visited[i])
57                 {
58                     minn=dis[i];
59                     j=i;
60                 }
61             }
62             visited[j]=1;
63             b=j;
64             sum+=minn;
65         }
66         printf("%d\n",sum);
67     }
68     return 0;
69 }
时间: 2024-08-02 11:36:32

引水工程 Kruskal + Prim的相关文章

hdu 1863 畅通工程 kruskal || prim

简单最小生成树,畅通工程,这三道题目都是练习最小生成树的. 注意一下判断是否有通路时,kruskal可以判断每个点的祖先是否相同,prim可以判断每个点是否都加进集合里面了,也就是说是否都访问过.prim算法要把没有给的边初始化为MAX无穷大... 代码:(kruskal) #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath>

nyoj 1239——引水工程——————【最小生成树 prim】

引水工程 时间限制:2000 ms  |  内存限制:65535 KB 难度:3 描述 南水北调工程是优化水资源配置.促进区域协调发展的基础性工程,是新中国成立以来投资额最大.涉及面最广的战略性工程,事关中华民族长远发展.“南水北调工程”,旨在缓解中国华北和西北地区水资源短缺的国家战略性工程.就是把中国长江流域丰盈的水资源抽调一部分送到华北和西北地区.我国南涝北旱,南水北调工程通过跨流域的水资源合理配置,促进南北方经济.社会与人口.资源.环境的协调发展. 整个工程分东线.中线.西线三条调水线.东

nyoj 1239 引水工程 (河南省第八届acm程序设计大赛)

题目1239 题目信息 运行结果 本题排行 讨论区 引水工程 时间限制:2000 ms  |  内存限制:65535 KB 难度:3 描述 南水北调工程是优化水资源配置.促进区域协调发展的基础性工程,是新中国成立以来投资额最大.涉及面最广的战略性工程,事关中华民族长远发展."南水北调工程",旨在缓解中国华北和西北地区水资源短缺的国家战略性工程.就是把中国长江流域丰盈的水资源抽调一部分送到华北和西北地区.我国南涝北旱,南水北调工程通过跨流域的水资源合理配置,促进南北方经济.社会与人口.资

Nyoj 引水工程(最小生成树)

描述 南水北调工程是优化水资源配置.促进区域协调发展的基础性工程,是新中国成立以来投资额最大.涉及面最广的战略性工程,事关中华民族长远发展.“南水北调工程”,旨在缓解中国华北和西北地区水资源短缺的国家战略性工程.就是把中国长江流域丰盈的水资源抽调一部分送到华北和西北地区.我国南涝北旱,南水北调工程通过跨流域的水资源合理配置,促进南北方经济.社会与人口.资源.环境的协调发展. 整个工程分东线.中线.西线三条调水线.东线工程位于东部,因地势低需抽水北送至华北地区.中线工程从汉水与其最大支流丹江交汇处

第八届河南省赛D.引水工程(kruthcra+prime)

D.引水工程 Time Limit: 2 Sec  Memory Limit: 128 MB Submit: 118  Solved: 41 [Submit][Status][Web Board] Description 南水北调工程是优化水资源配置.促进区域协调发展的基础性工程,是新中国成立以来投资额最大.涉及面最广的战略性工程,事关中华民族长远发展. “南水北调工程”,旨在缓解中国华北和西北地区水资源短缺的国家战略性工程.就是把中国长江流域丰盈的水资源抽调一部分送到华北和西北地区.我国南涝北

zzuoj 10409 10409: D.引水工程

10409: D.引水工程 Time Limit: 2 Sec  Memory Limit: 128 MBSubmit: 96  Solved: 34[Submit][Status][Web Board] Description 南水北调工程是优化水资源配置.促进区域协调发展的基础性工程,是新中国成立以来投资额最大.涉及面最广的战略性工程,事关中华民族长远发展. “南水北调工程”,旨在缓解中国华北和西北地区水资源短缺的国家战略性工程.就是把中国长江流域丰盈的水资源抽调一部分送到华北和西北地区.我

ACM:最小生成树,kruskal &amp;&amp; prim,并查集

题目: 输入顶点数目,边的数目,输入每条边的两个顶点编号还有每条边的权值,求最小生成树,输出最小生成树的权值.. 注意:prim算法适合稠密图,其时间复杂度为O(n^2),其时间复杂度与边得数目无关,而kruskal算法的时间复杂度为O(eloge)跟边的数目有关,适合稀疏图. kruskal----归并边:prim----归并点 方法一:kruskal,克鲁斯卡尔,并查集实现. #include <iostream> #include <algorithm> using name

NYOJ 1239 引水工程 【MST 变形】

引水工程 时间限制:2000 ms  |  内存限制:65535 KB 难度:3 描述 南水北调工程是优化水资源配置.促进区域协调发展的基础性工程,是新中国成立以来投资额最大.涉及面最广的战略性工程,事关中华民族长远发展."南水北调工程",旨在缓解中国华北和西北地区水资源短缺的国家战略性工程.就是把中国长江流域丰盈的水资源抽调一部分送到华北和西北地区.我国南涝北旱,南水北调工程通过跨流域的水资源合理配置,促进南北方经济.社会与人口.资源.环境的协调发展. 整个工程分东线.中线.西线三条

POJ-2421Constructing Roads,又是最小生成树,和第八届河南省赛的引水工程惊人的相似,并查集与最小生成树的灵活与能用,水过~~~

Constructing Roads Time Limit: 2000MS   Memory Limit: 65536K               Description There are N villages, which are numbered from 1 to N, and you should build some roads such that every two villages can connect to each other. We say two village A