The lowest cost construction problem of unblocked project

Title description:
After surveying urban traffic conditions in a certain area, statistics on existing inter-town express roads are obtained, and the goal of the "Unblocked Project" is proposed: to enable rapid transportation between any two towns in the entire area (but not necessarily There are direct expressways connected, as long as each other is indirectly reachable through expressways). A statistical table of urban roads is now available. The table lists the cost of several roads that may be built into expressways, and seeks the lowest cost required for a smooth project.

Input format:
The first line of input gives the number of towns N (1<N≤1000) and the number of candidate roads M≤3N; the following M lines, each line gives 3 positive integers, which are directly connected to the road The number of the two towns (numbered from 1 to N) and the budgeted cost of the road reconstruction.

Output format:
output the minimum cost required for a smooth project. If the input data is not enough to ensure smooth flow, output "Impossible".

Input example 1:
6 15
1 2 5
1 3 3
1 4 7
1 5 4
1 6 2
2 3 4
2 4 6
2 5 2
2 6 6
3 4 6
3 5 1
3 6 1
4 5 10
4 6 8
5 6 3
Output example 1:
12

Input example 2:
5 4
1 2 1
2 3 2
3 1 3
4 5 4
Output example 2:
Impossible

Illustration of sample input 2:
Insert picture description here
Obviously, sample input 2 cannot be guaranteed to be unblocked, so the output is Impossible.

Illustration of sample input 1:
Insert picture description here
At first glance, sample input 1 is complicated. Let's analyze it step by step. It is obvious from the figure that the input data can ensure smooth flow. The sample output 1:12 is the sum of the weights of the edges of the minimum spanning tree of the graph.

Known from the question: This question requires the lowest cost required for a smooth project. That is, under the premise of ensuring that the vertices in the graph are connected, the lowest cost is also required, which has a hint of seeking the minimum spanning tree of the graph. There are two well-known algorithms for constructing the minimum spanning tree: Prim algorithm and Kruskal algorithm.

The solution using kruskal algorithm is given below. (Please refer to the code below for specific steps)

As usual, the code first:

#include <stdio.h>
#include <stdlib.h>//qsort()函数的头文件。

#define MAXVERTEXNUM 1001//城镇数目N(1<N≤1000)。
#define MAXEDGENUM 3001 //候选道路数目M≤3N。

/*typedef定义新的数据类型,相当于给该结构体取一个别名Road,该结构体类型即Road类型,
与此同时,定义了一个名为road的指针类型指向该结构体。
该结构体中的成员v1代表连通的城镇中其中一个城镇的编号,
               v2代表连通的城镇中另外一个城镇的编号,
               cost代表连通的城镇道路改建的预算成本。 */
typedef struct{
    
    
	int v1;
	int v2;
	int cost;
}Road,*road;

Road a[MAXEDGENUM];//定义了一个Road类型的数组,该数组名为a。
int parent[MAXVERTEXNUM];//定义了一个int类型的数组,该数组名为parent。

/*并查集之初始化操作*/
void init(int n)
{
    
    
 int i;
 for(i=1;i<=n;i++)
  	parent[i]=i;//城镇编号从1到N,将每个顶点(城镇)的父结点设置为自己。
}

/*并查集之寻找根节点操作*/
int find_root(int x)
{
    
    
	if(x==parent[x])//如果该元素的父结点是其自己,则说明该元素为根结点,返回该元素的编号。
	 return x;
	else
	/*否则递归地去寻找该元素的根结点,
	递归操作顺便把从根到该结点路径上的所有结点都直接放到根节点下。*/
	 return parent[x]=find_root(parent[x]);//压缩路径
	 //补充:压缩路径的好处:有可能降低了树高,提高以后的查询效率。
}

/*qsort()比较函数,该函数名为cmp。
根据结构体中的关键字cost,对结构体进行升序排序。*/
int cmp(const void *a,const void *b)
{
    
    
	road pa=(road)a;
	road pb=(road)b;
	int num1=pa->cost;
	int num2=pb->cost;
	return num1-num2;
}

int main()
{
    
    
	int N,M,i,sum=0,count=0;
	scanf("%d%d",&N,&M);//输入数据城镇数目N和候选道路数目M。
	
	for(i=0;i<M;i++)
	{
    
    
		scanf("%d%d%d",&a[i].v1,&a[i].v2,&a[i].cost);
		/*随后的M行,每行给出3个正整数,
		分别是该条道路直接连通的两个城镇的编号(从1编号到N)以及该道路改建的预算成本。*/
	}
	
	qsort(a,M,sizeof(Road),cmp);//qsort()函数对a数组根据结构体的关键字cost进行升序排序。*/
	
	init(N);//初始化操作。

    /*查找连通城镇中其中一个城镇的父结点
      和另外一个城镇的父结点。如果它们的父结点不同,则对它们进行合并操作,并将该结构体的cost关键字
      加到变量sum中。(kruskal算法的主体部分)*/
	for(i=0;i<M;i++)
	{
    
    
	  int A=find_root(a[i].v1);
	  int B=find_root(a[i].v2);
	  if(A!=B)
	  {
    
    
	  	parent[A]=B;
	  	sum+=a[i].cost;
	  }	
	}
	
	/*从第一个结点开始,查找其父结点是否是其本身。如果是的话,则对变量count进行自增操作。*/
	for(i=1;i<=N;i++)
	{
    
    
		if(parent[i]==i)
		 count++;
	}
    
    /*判断变量count是否为1,如果变量count为1,则说明该图是一个连通图,
    输入数据能保证城镇畅通,输出畅通工程需要的最低成本sum;
    否则,说明输入数据不足以保证城镇畅通,输出Impossible。*/
    if(count!=1)
     printf("Impossible");
    else
     printf("%d",sum);
	return 0;
}

In general, this question mainly examines Kruskal's algorithm. In general, it is a template question.
Let’s stop here for this sharing. If you have any questions, please leave a message in the comment area. Thank you for your support!

Guess you like

Origin blog.csdn.net/qq_46139801/article/details/113816510