The tenth question of the 11th Lanqiao Cup Provincial Simulation Competition C++ (prim algorithm)

Problem Description

In 2015, every household in China was connected to electricity. As a power builder, Xiao Ming is helping countries along the Belt and Road get electricity.
  This time, Xiao Ming wants to help n villages get electricity, and village No. 1 can just build a power station, and the electricity generated is enough for all villages.
  Now, there are no wires connecting these n villages. What Xiaoming mainly needs to do is to connect these villages with wires, so that all villages are directly or indirectly connected to the power station.
  Xiao Ming has measured the positions (coordinates) and heights of all villages. If he wants to connect two villages, Xiao Ming needs to spend the coordinate distance between the two villages plus the square of the height difference. The formal description is that the coordinates are (x_1, y_1) height The cost of connecting a village at h_1 to a village at height h_2 at coordinates (x_2, y_2) is
  sqrt((x_1-x_2)(x_1-x_2)+(y_1-y_2)(y_1-y_2))+(h_1 -h_2)*(h_1-h_2).
  In the above formula, sqrt means to take the square root in the brackets. Please pay attention to the position of the brackets, the calculation method of height is different from the calculation method of horizontal and vertical coordinates.
  Due to limited funds, please help Xiao Ming calculate how much he needs to spend at least to electrify all n villages.

input format

The first line of input contains an integer n denoting the number of villages.
  In the next n lines, each three integers x, y, h represent the abscissa, y, and height of a village, and the first village can build a power station.

output format

Output a line containing a real number rounded to 2 decimal places to represent the answer.

sample input

4
1 1 3
9 9 7
8 8 6
4 5 4

sample output

17.41

Evaluation use case scale and agreement

For 30% of the evaluation cases, 1 <= n <= 10;
  for 60% of the evaluation cases, 1 <= n <= 100;
  for all evaluation cases, 1 <= n <= 1000, 0 <= x, y, h <= 10000.
  
Answer idea: This is a classic minimum spanning tree problem. The data test here is up to 1000, so we can use the adjacency matrix to store this graph. If there are more than 1000, we can use the adjacency list to do it;

#include<iostream> 
#include<math.h>
#include<stdio.h>
using namespace std;
const int Max=1000;//最多1000个节点;
double  jz[Max][Max];//构造邻接矩阵;
const double inf=9999.9;
int n;//有多少个村庄 
int vis[Max]={
    
    0};//用来判断这个节点是否被访问了,初始化为0 
double d[Max]; //d[i]代表着第i个节点到这个s集合里面的最短距离 
void init()//初始化领接矩阵 
{
    
    
	for(int i=0;i<n;i++)
	{
    
    
		for(int j=0;j<n;j++)
		{
    
    
			jz[i][j]=inf;
		}
	}
}
void init1()//初始化d[Max]; 
{
    
    
	for(int i=0;i<n;i++)
	{
    
    
		d[i]=inf;
	}
}
double prim()//prim算法 
{
    
        
	
    double ans=0; 
	init1();//这里注意一定先初始化d[Max],在对第一个赋值 
    d[0]=0;
    for(int i=0;i<n;i++)
    {
    
    
    	int u=-1;
		double min=inf;
    	for(int j=0;j<n;j++)
    	{
    
        
    	    if(vis[j]==0&&d[j]<min)//将当前可以访问到s集合里面的顶点,并且是距离最短的加入到s集合中 
			{
    
    
			
				u=j;
				min=d[j];	
			}	  
    	}
    	if(u==-1)
    	{
    
    
    		return -1;
    	}
    	ans+=d[u];
    	vis[u]=1;//将节点设置为访问过了 
    	for(int v=0;v<n;v++)
    	{
    
         
    		if(vis[v]==0&&jz[u][v]!=inf&&jz[u][v]<d[v])//与当前没有访问过的节点&&可以访问到u节点&&到这个u的距离比到s集合的最短距离要小 
    		{
    
    	
    			d[v]=jz[u][v];
    		}
    			
    	}	
    }
	return ans;	
} 
double js(int x1,int y1,int h1,int x2,int y2,int h2)
{
    
    
	double w= sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))+(h1-h2)*(h1-h2);	
	return w;
}
int main()
{
    
    
    cout<<"请输入村庄的数量:";
	cin>>n;
	int num[n][3];
	init();
	cout<<"请输入每个村子的X,Y,H:"<<endl;
	for(int i=0;i<n;i++)
	{
    
    	
		cin>>num[i][0]>>num[i][1]>>num[i][2]; 	
	}
    for(int i=0;i<n;i++)
    {
    
    
    	for(int j=0;j<n;j++)
    	{
    
    	
    		if(i!=j)
    		{
    
    
    			double w;//两个之间建立电路的金额 
    			w=js(num[i][0],num[i][1],num[i][2],num[j][0],num[j][1],num[j][2]);
    			jz[i][j]=w;		
    		}
    	}
    } 
	printf("%.2lf",prim());
	return 0;
}

Summary; I use the more traditional prim algorithm to solve the problem. I basically apply the prim algorithm in the book. For this problem, I mainly pay attention to the data types inside.

Guess you like

Origin blog.csdn.net/qq_44741914/article/details/105624834
Recommended