Hdu1102-Constructing Roads

题目链接:
传送门

Problem 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 and B are connected, if and only if there is a road between A and B, or there exists a village C such that there is a road between A and C, and C and B are connected.
We know that there are already some roads between some villages and your job is the build some roads such that all the villages are connect and the length of all the roads built is minimum.

Input:
The first line is an integer N (3 <= N <= 100), which is the number of villages. Then come N lines, the i-th of which contains N integers, and the j-th of these N integers is the distance (the distance should be an integer within [1, 1000]) between village i and village j.
Then there is an integer Q (0 <= Q <= N * (N + 1) / 2). Then come Q lines, each line contains two integers a and b (1 <= a < b <= N), which means the road between village a and village b has been built.

Output:
You should output a line contains an integer, which is the length of all the roads to be built such that all the villages are connected, and this value is minimum.

Sample Input:
3
0 990 692
990 0 179
692 179 0
1
1 2

Sample Output:
179

中文版:
题目描述:
一共有N个村庄,从1到N编号,你应该建造一些道路,这样每两个村庄就可以连接起来。我们说两个村庄A和B是连接的,当且仅当在A和B之间有一条路,或者存在一个村庄C在A和C之间有一条路,并且C和B是连接的。
我们知道一些村庄之间已经有了一些道路,你的工作就是修建一些道路,这样所有的村庄都能连接起来,所有道路的长度都是最小的。

输入:
第一行是整数N (3 <= N <= 100),表示村庄的数量。接下来的N行,第i行包含N个整数,N个整数中的第j个整数表示村庄i和村庄j之间的距离(距离应该是[1,1000]内的整数)。
然后有一个整数Q (0 <= Q <= N * (N + 1) / 2),然后有Q行,每一行包含两个整数a和b (1 <= a <b <= N),这意味着a村和b村之间的道路已经建成。

输出:
你应该输出一行包含一个整数,它是所有要建设的道路的长度,这样所有的村庄都可以连接起来,这个值是最小的。

样例输入:
3
0 990 692
990 0 179
692 179 0
1
1 2

样例输出:
179

扫描二维码关注公众号,回复: 13109415 查看本文章

样例示意图:
在这里插入图片描述

kruskal算法c参考代码:

#include <stdio.h>
#include <string.h>

#define VERTEXMAX 101
#define EDGEMAX 10100
 
int n,q;
int parent[VERTEXMAX];

typedef struct{
    
    
	int v1;
	int v2;
	int w;
}Road,*road;

Road a[EDGEMAX];

int cmp(const void *a,const void *b)
{
    
    
	road pa=(road)a;
	road pb=(road)b;
	int num1=pa->w;
	int num2=pb->w;
	return num1-num2;
}

void init()
{
    
    
	int i;
	for(i=1;i<=n;i++)
	 parent[i]=i;
}

int find(int x)
{
    
    
	if(x==parent[x])
	 return x;
	else
	 return parent[x]=find(parent[x]);
}

void kruskal(int num)
{
    
    
	int i,sum=0;
	
	for(i=0;i<num;i++)
	{
    
    
		int x=a[i].v1;
		int y=a[i].v2;
		int A=find(x);
		int B=find(y);
		if(A!=B)
		{
    
    
		   parent[A]=B;
		   sum+=a[i].w;
		}
	}
	printf("%d\n",sum);
}

int main()
{
    
    
	while(scanf("%d",&n)!=EOF)
	{
    
    
	   memset(a,0,sizeof(a));
	   init();
	   
	   int i,j,k,x,y,num=0;
	   for(i=1;i<=n;i++)
	   {
    
    
	   	for(j=1;j<=n;j++)
	   	{
    
    
	   		scanf("%d",&k);
	   		if(i>=j)
	   		 continue;
			a[num].v1=i;
	   		a[num].v2=j;
	   		a[num++].w=k;
		}
	   }
	   
	   qsort(a,num,sizeof(Road),cmp);
	   
	   scanf("%d",&q);
	   for(i=0;i<q;i++)
	  {
    
    
		scanf("%d%d",&x,&y);
		int A=find(x);
		int B=find(y);
		parent[A]=B;
	  }
	  
	   kruskal(num);
	}
	return 0;
} 

prim算法c参考代码:

#include <stdio.h>
#include <string.h>

#define MAX 101
#define INF 0x3f3f3f3f
 
int dist[MAX];
int visited[MAX];
int map[MAX][MAX];
int n,q;

void prim(int s)
{
    
    
	memset(visited,0,sizeof(visited));
	int i,j,sum=0;
	for(i=1;i<=n;i++)
	 dist[i]=map[s][i];
	
	visited[s]=1;
	
	for(i=1;i<n;i++)
	{
    
    
		int min=INF,pos;
		for(j=1;j<=n;j++)
		{
    
    
			if(visited[j]==0&&dist[j]<min)
			{
    
    
				min=dist[j];
				pos=j;
			}
		}
		
		visited[pos]=1;
		sum+=min;
		
		for(j=1;j<=n;j++)
		{
    
    
			if(visited[j]==0&&dist[j]>map[pos][j])
			 dist[j]=map[pos][j];
		}
	}
	
	printf("%d\n",sum);
}

int main()
{
    
    
    int i,j,x,y;
	while(scanf("%d",&n)!=EOF)
	{
    
    	
		for(i=1;i<=n;i++)
		{
    
    
			for(j=1;j<=n;j++)
			{
    
    
			  scanf("%d",&map[i][j]);
			}
		}
		
		scanf("%d",&q);
		for(i=0;i<q;i++)
		{
    
    
			scanf("%d%d",&x,&y);
			map[x][y]=map[y][x]=0;
		}
		
		prim(1);
	}
	return 0;
}

参考资料传送门:
prim算法求解:
传送门
kruskal算法求解:
传送门

猜你喜欢

转载自blog.csdn.net/qq_46139801/article/details/114481391