百练/ 北京大学2016研究生推免上机考试(校外)G: Tangled in Cables(最小支撑树)

题目来源:http://bailian.openjudge.cn/practice/2075/

2075:Tangled in Cables

总时间限制:1000ms  内存限制: 65536kB

描述

You are the owner of SmallCableCo and have purchased thefranchise rights for a small town. Unfortunately, you lack enough funds tostart your business properly and are relying on parts you have found in an oldwarehouse you bought. Among your finds is a single spool of cable and a lot ofconnectors. You want to figure out whether you have enough cable to connectevery house in town. You have a map of town with the distances for all thepaths you may use to run your cable between the houses. You want to calculatethe shortest length of cable you must have to connect all of the housestogether.

输入

Only one town will be given in an input.

  • The first line gives the length of cable on the spool as a real number.
  • The second line contains the number of houses, N
  • The next N lines give the name of each house's owner. Each name consists of up to 20 characters {a–z,A–Z,0–9} and contains no whitespace or punctuation.
  • Next line: M, number of paths between houses
  • next M lines in the form


< house name A > < house name B > < distance >
Where the two house names match two different names in the list above and thedistance is a positive real number. There will not be two paths between thesame pair of houses.

输出

The output will consist of a single line. If there is notenough cable to connect all of the houses in the town, output
Not enough cable
If there is enough cable, then output
Need < X > miles of cable
Print X to the nearest tenth of a mile (0.1).

样例输入

100.0

4

Jones

Smiths

Howards

Wangs

5

Jones Smiths 2.0

Jones Howards 4.2

Jones Wangs 6.7

Howards Wangs 4.0

Smiths Wangs 10.0

样例输出

Need 10.2 miles of cable

-----------------------------------------------------

解题思路

Prime算法求最小支撑树。

-----------------------------------------------------

代码

#include<iostream>
#include<fstream>
#include<string>
#include<map>
#include<math.h>
using namespace std;

const double MAX_DOUBLE = 10000;

int Round(double a)
{
	int as = floor(a);
	int at = a - as;
	if (at>0.5)
	{
		return (as+1);
	}
	else
	{
		return as;
	}
}


int main()
{
#ifndef ONLINE_JUDGE
	ifstream fin("tm201602G.txt");
	double total, thelen;
	fin >> total;
	int n,m,i,j,k;
	fin >> n;
	string hn,hn1;
	map<string,int> HN;
	for (i=0; i<n; i++)
	{
		fin >> hn;
		HN[hn] = i;
	}
	double **mat = new double*[n];
	for (i=0; i<n; i++)
	{
		mat[i] = new double[n]();
	}
	fin >> m;
	for (i=0; i<m; i++)
	{
		fin >> hn >> hn1 >> thelen;
		mat[HN[hn]][HN[hn1]] = thelen;
		mat[HN[hn1]][HN[hn]] = thelen;
	}
	fin.close();
	// Prime algorithm
	double ans = 0, Min = MAX_DOUBLE;
	int minNode = 0;
	bool *marked = new bool[n]();
	marked[0] = 1;
	for (i=1; i<n; i++)
	{
		if (mat[0][i] != 0 && mat[0][i] < Min)
		{
			Min = mat[0][i];
			minNode = i;
		}
	}
	marked[minNode] = 1;
	ans += Min;
	for (i=2; i<n; i++)
	{
		Min = MAX_DOUBLE;
		for (j=0; j<n; j++)
		{
			if (marked[j])
			{
				for (k=0; k<n; k++)
				{
					if (!marked[k] && mat[j][k]!=0 && mat[j][k]<Min)
					{
						Min = mat[j][k];
						minNode = k;
					}

				}

			}

		}
		marked[minNode] = 1;
		ans += Min;
	}
	if (ans > total)
	{
		cout << "Not enough cable";
	}
	else
	{
		int ansint = Round(10*ans);
		cout << "Need " << ansint/10 << "." << ansint%10 << " miles of cable";
	}
	for (i=0; i<n; i++)
	{
		delete[] mat[i];
	}
	delete[] mat;
	return 0;
#endif
#ifdef ONLINE_JUDGE
	double total, thelen;
	cin >> total;
	int n,m,i,j,k;
	cin >> n;
	string hn,hn1;
	map<string,int> HN;
	for (i=0; i<n; i++)
	{
		cin >> hn;
		HN[hn] = i;
	}
	double **mat = new double*[n];
	for (i=0; i<n; i++)
	{
		mat[i] = new double[n]();
	}
	cin >> m;
	for (i=0; i<m; i++)
	{
		cin >> hn >> hn1 >> thelen;
		mat[HN[hn]][HN[hn1]] = thelen;
		mat[HN[hn1]][HN[hn]] = thelen;
	}
	// Prime algorithm
	double ans = 0, Min = MAX_DOUBLE;
	int minNode = 0;
	bool *marked = new bool[n]();
	marked[0] = 1;
	for (i=1; i<n; i++)
	{
		if (mat[0][i] != 0 && mat[0][i] < Min)
		{
			Min = mat[0][i];
			minNode = i;
		}
	}
	marked[minNode] = 1;
	ans += Min;
	for (i=2; i<n; i++)
	{
		Min = MAX_DOUBLE;
		for (j=0; j<n; j++)
		{
			if (marked[j])
			{
				for (k=0; k<n; k++)
				{
					if (!marked[k] && mat[j][k]!=0 && mat[j][k]<Min)
					{
						Min = mat[j][k];
						minNode = k;
					}

				}

			}

		}
		marked[minNode] = 1;
		ans += Min;
	}
	if (ans > total)
	{
		cout << "Not enough cable";
	}
	else
	{
		int ansint = Round(10*ans);
		cout << "Need " << ansint/10 << "." << ansint%10 << " miles of cable";
	}
	for (i=0; i<n; i++)
	{
		delete[] mat[i];
	}
	delete[] mat;
	return 0;
#endif
}


猜你喜欢

转载自blog.csdn.net/da_kao_la/article/details/80266783