HDOJ 1233 还是畅通工程(并查集)

2023-12-17 04:38
文章标签 工程 查集 畅通 hdoj 1233

本文主要是介绍HDOJ 1233 还是畅通工程(并查集),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!



http://acm.hdu.edu.cn/showproblem.php?pid=1233

还是畅通工程

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


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
Hint
Huge input, scanf is recommended.
第一次写时WA找不到错误,第二次在第一次写的基础上改变了判断两村庄在前边的合并下已经在一个集合中的代码(第一次代码的67~83行),然后过了,这样看来应该是这里的错,但始终不知道为什么,大神指教。
先贴第二次AC的代码,代码后边附带几组测试数据。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int set[10000];
struct Road
{int NUM_1;int NUM_2;int distance;
}roads[10000];int cmp(const void *a,const void *b)
{return ((Road *)a)->distance - ((Road *)b)->distance;
}
int Find(int x)
{int r=x,i=x,j;while(set[r]!=r)r=set[r];while(i!=r){j=set[i];set[i]=r;i=j;}return r;
}
void merge(int x,int y)
{x=Find(x);y=Find(y);if(y<x)set[x]=y;if(x<y)set[y]=x;
}
int main()
{int T,N,i,j,k,S,sum;while(scanf("%d",&T)&&T!=0){memset(set,0,sizeof(set));N=T*(T-1)/2;set[0]=-1;//后边要排序,用不到set[0],所以给他赋-1让他始终在第一个,不影响后边的数 for(i=1;i<=T;i++)//初始化,每个村庄都是独立的,即每个数的根就是自己 set[i]=i;for(i=1;i<=N;i++)scanf("%d %d %d",&roads[i].NUM_1,&roads[i].NUM_2,&roads[i].distance);qsort(roads,N+1,sizeof(roads[0]),cmp);///按道路从小到大排序结构体 for(i=1,sum=0;i<=N;i++)///到i组数据时,全部的村庄连通 {if(Find(roads[i].NUM_1)!=Find(roads[i].NUM_2))//判断村庄NUM_1和NUM_2是否有相同的根 sum+=roads[i].distance;//若没有把NUM_1和NUM_2之间的卢修建起来 merge(roads[i].NUM_1,roads[i].NUM_2);//再把NUM_1和NUM_2归于一个根(合并到一个集合里) for(j=1,S=0;j<=T;j++)//所有的村庄是否连通 if(set[j]==j)S+=1;if(S==1)//连通则跳出 break;}printf("%d\n",sum);}return 0;
}
/*
5
1 2 5
1 3 5
1 4 5
1 5 5
2 3 4
2 4 4
2 5 4
3 4 3
3 5 3
4 5 26
1 2 6
1 3 6
1 4 6
1 5 6
1 6 6
2 3 5
2 4 5
2 5 5
2 6 5
3 4 4
3 5 4
3 6 4
4 5 3
4 6 3
5 6 214
20
*/

下面是第一次WA的代码
//此程序能想到的测试数据都对,但就是WA。
//改了一下这个程序的判断村庄是否出现代码(67~83行),改成在合并时就判断。但感觉现在的也没错,求大神指教。 
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int set[10000];
struct Road
{int NUM_1;int NUM_2;int distance;
}roads[10000];int cmp(const void *a,const void *b)
{return ((Road *)a)->distance - ((Road *)b)->distance;
}
int Find(int x)
{int r=x,i=x,j;while(set[r]!=r)r=set[r];while(i!=r){j=set[i];set[i]=r;i=j;}return r;
}
void merge(int x,int y)
{x=Find(x);y=Find(y);if(y<x)set[x]=y;if(x<y)set[y]=x;
}
int main()
{int T,N,i,j,k,S,sum;while(scanf("%d",&T)&&T!=0){memset(set,0,sizeof(set));N=T*(T-1)/2;set[0]=-1;//后边要排序,用不到set[0],所以给他赋-1让他始终在第一个,不影响后边的数 for(i=1;i<=T;i++)//初始化,每个村庄都是独立的,即每个数的根就是自己 set[i]=i;for(i=1;i<=N;i++)scanf("%d %d %d",&roads[i].NUM_1,&roads[i].NUM_2,&roads[i].distance);qsort(roads,N+1,sizeof(roads[0]),cmp);///按道路从小到大排序结构体 for(i=1;i<=N;i++)///到i组数据时,全部的村庄连通 {merge(roads[i].NUM_1,roads[i].NUM_2);for(j=1,S=0;j<=T;j++)if(set[j]==j)S+=1;if(S==1)break;}if(N==0/*也就是T==1*/) i=0;for(j=1,sum=0;j<=i;j++){int judge_1=0,judge_2=0;//判断前边的道路是否已经把两个村庄已经连通//judge_1==0,judge_2==0分别表示没有连通    for(k=1;k<j;k++){if(roads[k].NUM_1==roads[j].NUM_1||roads[k].NUM_2==roads[j].NUM_1)judge_1=1;if(roads[k].NUM_1==roads[j].NUM_2||roads[k].NUM_2==roads[j].NUM_2)judge_2=1;}if(judge_1==1&&judge_2==1)continue;elsesum+=roads[j].distance;} printf("%d\n",sum);}return 0;
}


这篇关于HDOJ 1233 还是畅通工程(并查集)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/503077

相关文章

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

XTU 1233 n个硬币连续m个正面个数(dp)

题面: Coins Problem Description: Duoxida buys a bottle of MaiDong from a vending machine and the machine give her n coins back. She places them in a line randomly showing head face or tail face o

poj 1182 并查集 食物链类

题意: 有n只动物,分别编号1....n。所有动物都属于A,B,C中的一种,已知A吃B,B吃C,C吃A。 按顺序给出下面两种共K条信息: 1. x 和 y 属于同一类。 2. x 吃 y 。 然而这些信息可能会出错,有可能有的信息和之前给出的信息矛盾,也有的信息可能给出的 x 和 y 不在n的范围内。 求k条信息中有多少条是不正确的。 解析: 对于每只动物,创建3个元素 i

POJ1988带权并查集

M u v 将u所在的堆移动到v所在的堆的上面 C u 求u的下面有多少块 带权并查集 import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWriter;import java.math.BigInteger;i

POJ1703带权并查集

D: u v  u与v在不同的集合 A: u v  查询u与v的关系 1)压缩路径过程        fu->root   0  1  u-fu 0                 0  1   1                 1  0 2)合并过程 fu->fv      u->fu   0 1   v->fv 0            1 0 1            0

Jenkins构建Maven聚合工程,指定构建子模块

一、设置单独编译构建子模块 配置: 1、Root POM指向父pom.xml 2、Goals and options指定构建模块的参数: mvn -pl project1/project1-son -am clean package 单独构建project1-son项目以及它所依赖的其它项目。 说明: mvn clean package -pl 父级模块名/子模块名 -am参数

二、Maven工程的创建--JavaSEJavaEE

1、idea创建Maven JavaSE工程:  2、idea创建Maven JavaEE工程:   (1)手动创建 (2)插件方式创建 在idea里安装插件JBLJavaToWeb; 选择需要生成的项目文件后,右击: 项目的webapp文件夹出现小蓝点,代表成功。

三、Maven工程的构建

首先,创建和构建是两个概念。 构建是指将源代码、依赖库和资源文件等转换为可执行或可部署的应用程序的过程。 在这个过程中包括编译源代码、链接依赖库、打包和部署等多个步骤。 项目构建是软件开发过程中至关重要的一部分,它能够大大提高软件开发效率,使得开发人员更加专注于应用程序的开发和维护,而不必关心应用程序的构建细节。 同时,项目构建还能将多人写的代码聚合,并能够自动化项目的构建和部署,

我在高职教STM32——准备HAL库工程模板(1)

新学期开学在即,又要给学生上 STM32 嵌入式课程了。这课上了多年了,一直用的都是标准库来开发,已经驾轻就熟了。人就是这样,有了自己熟悉的舒适圈,就很难做出改变,老师上课也是如此,排斥新课和不熟悉的内容。显然,STM32 的开发,HAL 库已是主流,自己其实也在使用,只不过更换库就意味着教学内容有很大变化,自己也就迟迟没有迈出调整这一步。现在,是时候做出变化了,笔者计划保持教学项

java工程的导入jar包

由于现在学习java web,java工程导入jar包都忘记了。 在此想记录一下:工程项目名:右击 -- Build Path --add External Archives 点击会弹出一个框 ,选择你要导入的jar路径就可以了。