HDU 1102 Constructing Roads

Problem Description

There are N villages, whichare numbered from 1 to N, and you should build some roads such that every twovillages 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 Csuch 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 isthe build some roads such that all the villages are connect and the length ofall 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, thei-th of which contains N integers, and the j-th of these N integers is thedistance (the distance should be an integer within [1, 1000]) between village iand village j.

Then there is an integer Q (0 <= Q <= N * (N + 1) / 2). Then come Qlines, 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 linecontains an integer, which is the length of all the roads to be built such thatall 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个村庄,如果AB之间有路,BC之间有路,那么AC也是相通的。同时,有些村庄之间已经有路了。使修最短的路将所有村庄都连通,求修的长度。

方法:最小生成树。

 

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

struct load
{
    int v,u;
    int w;
}num[5008];

int p[102];

int cmp(const void *a,const void *b)
{
    struct load *c,*d;
    c = (struct load *)a;
    d = (struct load *)b;
    return c->w - d->w;
};

int root(int x)
{
    if(p[x]==x)
        return x;
    p[x] = root(p[x]);
    return p[x];
};

int main()
{
	int n, i, j, k, sum, x, y, a, b, c, d, q, z;
	while(scanf("%d",&n)!=EOF)
	{
		k = 0;
		memset(num, 0, sizeof(num));//初始化
		for(i=0;i<=n;i++)
		{
			p[i]=i;
		}//初始化并查集

		//输入
		for(i=0;i<n;i++)
		{
			for(j = 0;j<n;j++)
			{
				scanf("%d",&a);
				if(j>i)//将上三角矩阵保存
				{
					num[k].w = a;
					num[k].v = i+1;
					num[k].u = j+1;
					k++;
				}
			}
		}

		//输入已修建的路
		scanf("%d",&q);
		for(i = 0;i<q;i++)
		{
			scanf("%d%d",&b, &c);
			if(b==1)
			{
				num[c-2].w = 0;
			}
			else
			{
				z = 0;
				for(j=1;j<b;j++)
				{
					z += n - j;
				}
				z = z + c - b - 1;//找寻该点在上三角矩阵中的位数
			    num[z].w = 0;
			}
		}

		//处理
		qsort(num,n*(n-1)/2,sizeof(num[0]),cmp);//将其按照权值从小到大排序
		sum=0;
		for(i=0,j = 0;i<n*(n-1)/2;i++)
		{
			x = root(num[i].v);
			y = root(num[i].u);
			if(x!=y)
			{	
				sum+=num[i].w;
				p[x] = y;
				j++;
			}
			if(j==n-1)
				break;
		}

		//输出
		printf("%d\n",sum);
	}
	return 0;
}


 

你可能感兴趣的:(HDU 1102 Constructing Roads)