HDU - 1232 畅通工程 HDU - 1874畅通工程续 HDU - 1875畅通工程再续

题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=1232

题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=1874

题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=1875

畅通工程属于水题,直接用并查集就行,加个路径压缩那就更好。

畅通工程续这道题WA了N次,因为有一个地方没注意到就是一个城镇到另外一个城镇的有多条道路,

所以你一开始就要把最短的道路选出来。我用的是Prim算法思想,只是把集合点到集合点的最短距离改

成集合点到单源点距离,后来发现这种算法又叫Dijkstra算法,0ms AC,貌似比许多人写的Dijkstra算

法时间要少,内存空间占用也小。

畅通工程再续这道题可以采用最小生成树,有Prim算法,Kruskal算法,个人觉得这里Prim算法要优于

Kruskal算法,因为它给出的条件是坐标,那么每条边都要计算,边数为e=n(n-1)/2,时间复杂度为O(elog n),

并没有多大的优化。注意变量类型距离都要是double。

 1 /*HDU 1232*/
 2 #include<stdio.h>
 3 const int maxn=1000+5;
 4 int fa[maxn];
 5 void init(int n)
 6 {
 7     for(int i=1;i<=n;i++)
 8         fa[i]=0;
 9 }
10 int find_father(int x)
11 {
12     if(fa[x]==0)
13         return x;
14     fa[x]=find_father(fa[x]);
15     return fa[x];
16 }
17 void union_father(int x,int y)
18 {
19     int find_a=find_father(x),find_b=find_father(y);
20     if(find_a!=find_b)
21         fa[find_b]=find_a;
22 }
23 int main()
24 {
25     int t;
26     scanf("%d",&t);
27     while(t--){
28         int n,m,a,b;
29         scanf("%d%d",&n,&m);
30         init(n);
31         for(int i=1;i<=m;i++){
32             scanf("%d%d",&a,&b);
33             union_father(a,b);
34         }
35         int ans=0;
36         for(int i=1;i<=n;i++)
37             if(fa[i]==0)
38             ans++;
39         printf("%d\n",ans);
40     }
41     return 0;
42 }
 1 /*HDU 1874*/
 2 #include<stdio.h>
 3 #include<string.h>
 4 #define doumin(a,b) (a<b?a:b)
 5 #define INF 0x3f3f3f3f
 6 const int maxn=200+5,maxm=1000+10;
 7 int c[maxn][maxn],closest[maxn],s,t,m;
 8 bool flag[maxn];
 9 void prim(int n)
10 {
11     memset(flag,false,sizeof(bool)*(n+1));
12     flag[s]=true;
13     closest[s]=0;
14     for(int i=0;i<n;i++)
15     if(!flag[i])
16       closest[i]=c[s][i];
17     for(int i=1;i<n;i++){
18         int mincost=INF,j=s;
19         for(int k=0;k<n;k++){
20             if(mincost>closest[k] && !flag[k]){
21                 mincost=closest[k];
22                 j=k;
23             }
24         }
25         flag[j]=true;
26         for(int k=0;k<n;k++)
27             if(closest[k]>c[k][j]+mincost)
28                 closest[k]=c[k][j]+mincost;
29     }
30 }
31 int main()
32 {
33     int n;
34     while(scanf("%d%d",&n,&m)!=EOF){
35         int u,v,w;
36         for(int i=0;i<n;i++)
37         for(int j=0;j<n;j++)
38             c[i][j]=(i==j?0:INF);
39         for(int i=1;i<=m;i++){
40             scanf("%d%d%d",&u,&v,&w);
41             c[u][v]=c[v][u]=doumin(c[u][v],w);
42         }
43         scanf("%d%d",&s,&t);
44         prim(n);
45         if(closest[t]>=INF)
46             printf("-1\n");
47         else
48             printf("%d\n",closest[t]);
49     }
50     return 0;
51 }
 1 /*HDU 1875*/
 2 #include<stdio.h>
 3 #include<stdlib.h>
 4 #include<math.h>
 5 #include<string.h>
 6 #define INF 0x3f3f3f3f
 7 const int maxn=100+2;
 8 int x[maxn],y[maxn];
 9 double lowdist[maxn];
10 bool s[maxn];
11 double prim(int n)
12 {
13     double ans=0;
14     s[1]=true;
15     for(int i=2;i<=n;i++){
16         double t=(x[i]-x[1])*(x[i]-x[1])+(y[i]-y[1])*(y[i]-y[1]);
17         t=sqrt(t);
18         if(t>1000 || t<10)
19             t=INF;
20         lowdist[i]=t;
21         s[i]=false;
22     }
23     for(int i=1;i<n;i++){
24         double mindist=INF;
25         int j=1;
26         bool flag=true;
27         for(int k=2;k<=n;k++)
28             if(!s[k])
29             if(mindist>lowdist[k]){
30                     mindist=lowdist[k];
31                     j=k;
32                     flag=false;
33             }
34         s[j]=true;
35         if(flag)
36             return -1;
37         ans+=mindist;
38         for(int k=2;k<=n;k++){
39             if(!s[k]){
40                 double t=(x[k]-x[j])*(x[k]-x[j])+(y[k]-y[j])*(y[k]-y[j]);
41                 t=sqrt(t);
42                 if(t>1000 || t<10)
43                     continue;
44                 if(lowdist[k]>t)
45                     lowdist[k]=t;
46             }
47         }
48     }
49     return ans;
50 }
51 int main()
52 {
53     int t;
54     scanf("%d",&t);
55     while(t--){
56         int n;
57         scanf("%d",&n);
58         for(int i=1;i<=n;i++)
59             scanf("%d%d",&x[i],&y[i]);
60         double ansdist=prim(n);
61         if(ansdist<0)
62             printf("oh!\n");
63         else
64             printf("%0.1f\n",ansdist*100.0);
65     }
66     return 0;
67 }

HDU - 1232 畅通工程 HDU - 1874畅通工程续 HDU - 1875畅通工程再续

时间: 2024-11-29 01:29:28

HDU - 1232 畅通工程 HDU - 1874畅通工程续 HDU - 1875畅通工程再续的相关文章

HDU 1232 畅通工程(并查集)

畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 30485    Accepted Submission(s): 16013 Problem Description 某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇.省政府"畅通工程"的目标是使全省任何两个城镇间都可以实现交通(但不一定有

hdu 1232 畅通工程(最小生成树)

Problem Description 某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇.省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要互相间接通过道路可达即可).问最少还需要建设多少条道路? Input 测试输入包含若干测试用例.每个测试用例的第1行给出两个正整数,分别是城镇数目N ( < 1000 )和道路数目M:随后的M行对应M条道路,每行给出一对正整数,分别是该条道路直接连通的两个城镇的编号.为简单起见,城镇从1

HDU 1232(畅通工程)题解

以防万一,题目原文和链接均附在文末.那么先是题目分析: [一句话题意] 给定一具有N个节点的图和其边集,求其集合数量. [题目分析] 并查集经典题...其实就是创建好并查集就行了.. [算法流程] 于是这里就是放并查集的基本内容的..用一个数组的下标来对应节点,值来对应其父节点,并查集英文是Disjoint Sets,就叫DJSet好了XD 1 int getDjSetPar(int id) { //取得某节点的父节点 2 if (dj[id]==id) return id; 3 else re

hdu 1875 畅通工程再续(Kruskal算法)

题目来源:hdu 1875 畅通工程再续 畅通工程再续 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 20477 Accepted Submission(s): 6453 Problem Description 相信大家都听说一个"百岛湖"的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现.现在政

HDU 1875 畅通工程再续 (最小生成树 水)

Problem Description 相信大家都听说一个"百岛湖"的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现.现在政府决定大力发展百岛湖,发展首先要解决的问题当然是交通问题,政府决定实现百岛湖的全畅通!经过考察小组RPRush对百岛湖的情况充分了解后,决定在符合条件的小岛间建上桥,所谓符合条件,就是2个小岛之间的距离不能小于10米,也不能大于1000米.当然,为了节省资金,只要求实现任意2个小岛之间有路通即可.其中桥的价格为 100元/米.

hdu 1875 畅通工程再续 (最小生成树)

hdu 1875 畅通工程再续 Description 相信大家都听说一个"百岛湖"的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现.现在政府决定大力发展百岛湖,发展首先要解决的问题当然是交通问题,政府决定实现百岛湖的全畅通!经过考察小组RPRush对百岛湖的情况充分了解后,决定在符合条件的小岛间建上桥,所谓符合条件,就是2个小岛之间的距离不能小于10米,也不能大于1000米.当然,为了节省资金,只要求实现任意2个小岛之间有路通即可.其中桥的价格为

HDU 1875 畅通工程再续 (最小生成树)

畅通工程再续 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 14835    Accepted Submission(s): 4591 Problem Description 相信大家都听说一个“百岛湖”的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现.现在政府决定大力发展百岛湖,发展首先要解决的问题

HDU - 1875畅通工程再续-最小生成树

HDU - 1875 畅通工程再续 Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u Submit Status Description 相信大家都听说一个"百岛湖"的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现.现在政府决定大力发展百岛湖,发展首先要解决的问题当然是交通问题,政府决定实现百岛湖的全畅通!经过考察小组RPRush对百岛湖的情

【权值初始化+有条件的MST】hdu 1875 畅通工程再续

Source : hdu 1875 畅通工程再续 http://acm.hdu.edu.cn/showproblem.php?pid=1875 Problem Description 相信大家都听说一个"百岛湖"的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现.现在政府决定大力发展百岛湖,发展首先要解决的问题当然是交通问题,政府决定实现百岛湖的全畅通!经过考察小组RPRush对百岛湖的情况充分了解后,决定在符合条件的小岛间建上桥,所谓符合条件,就是2