UVa11710 - Expensive subway(最小生成树)

Expensive subway 

Peter lives in Expensive City, one of the most expensive cities in the world. Peter has not got enough money to buy a car, and the buses in Expensive City are pretty bad, so he uses the subway to go to work. Up to now, the subway was very cheap: you could travel anywhere with just one $2 ticket. Last month, the managers decided that it was too cheap so they invented the EFS (Expensive Fare System). With this system, users can only buy monthly tickets between adjacent stations, which allows them to move between these stations any number of times. The price of the monthly ticket varies between stations, so the decision of which tickets to buy must be taken carefully.

\epsfbox{p11710.eps}

With the previous subway plan, the cheapest way to travel from Picadilly to Victoria and Queensway was to buy the monthly ticket Picadilly-Victoria and Queensway-Victoria, for a total cost of $12.

Peter is a salesperson, so he needs to be able to travel to any part of the city. He wants to spend as little money as possible, and here is where you come into the picture. He has hired you to write a program that, given the list of stations, the fares of the monthly tickets between pairs of stations and the station nearest Peter's home, returns the minimum amount of money Peter has to spend in order to travel to any other station. This program also has to return value if it is not possible to go from Peter's home station to all the rest, because in this case Peter will begin to consider using buses...

Input 

The input consists of several test cases. A test case begins with a line containing two integers:1$ \le$s$ \le$400 (the number of stations) and 0$ \le$c$ \le$79800 (the number of connections) separated by a single space. This is followed by s lines, each one containing the name of a subway station. These names will be strings of characters (uppercase or lowercase) without punctuation marks or whitespace characters, and with a maximum length of 10 characters. After the names of the stations there will be c lines showing the connections between stations. A connection allows people to travel from one station to the other in both directions. Each connection is represented as two strings indicating the names of the stations and a positive integer indicating the cost of the monthly ticket, all of which are separated by single spaces. All names of stations appearing in the connections will have previously appeared in the list ofs stations. The connections will all be different, and there will not be any connection from a station to itself. The test case will end with a line containing the name of the station from which Peter needs to travel to all the other stations.

The input finishes with the phantom test case `0 0', which must not be processed.

Output 

For every test case, the output will be a line containing an integer, the minimum monthly price that Peter has pay to travel from the given station to all the others, or Impossible if it is not possible to travel to all the stations.

Sample Input 

3 3
Picadilly
Victoria
Queensway
Picadilly Victoria 2
Queensway Victoria 10
Queensway Picadilly 20
Picadilly
4 2
Picadilly
Victoria
Queensway
Temple
Picadilly Victoria 2
Temple Queensway 100
Temple
0 0

Sample Output 

12
Impossible
最小生成树(prim):

#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <vector>
#include <algorithm>

using namespace std;

const int N = 405;
const int INF = 0x7f7f7f7f;

struct Edge
{
	int from, to, c;
};

vector<int> adjList[N];
vector<Edge> edges;
map<string, int> m;
int s, c;
int start;
int d[N];
bool vis[N];

bool input();
void solve();
void addEdge(int u, int v, int cost);

int main()
{
#ifndef ONLINE_JUDGE
	freopen("d:\\OJ\\uva_in.txt", "r", stdin);
#endif

	while (input()) {
		solve();
	}

	return 0;
}

bool input()
{
	scanf("%d%d", &s, &c);
	if (s == 0 && c == 0) return false;
	
	m.clear();
	for (int i = 0; i < N; i++) adjList[i].clear();
	edges.clear();
	
	for (int i = 0; i < s; i++) {
		char buf[N];
		scanf("%s", buf);
		string s1 = buf;
		int size = m.size();
		m[s1] = size;
	}
	
	for (int i = 0; i < c; i++) {
		char buf1[N], buf2[N];
		int price;
		scanf("%s%s%d", buf1, buf2, &price);
		string s1 = buf1, s2 = buf2;
		int u = m[s1], v = m[s2];
		addEdge(u, v, price);
	}
	
	char buf[N];
	scanf("%s", buf);
	string s1 = buf;
	start = m[s1];
	
	return true;
}

void addEdge(int u, int v, int cost)
{
	edges.push_back((Edge){u, v, cost});
	edges.push_back((Edge){v, u, cost});
	
	adjList[u].push_back(edges.size() - 2);
	adjList[v].push_back(edges.size() - 1);
}

void solve()
{
	memset(vis, false, sizeof(vis));
	memset(d, 0x7f, sizeof(d));
	
	d[start] = 0;
	vis[start] = true;
	for (size_t i = 0; i < adjList[start].size(); i++) {
		Edge edge = edges[adjList[start][i]];
		int u = edge.to;
		int c = edge.c;
		d[u] = c;
	}
	
	bool ok;
	int ans = 0;
	for (int i = 0; i < s - 1; i++) {
		int Min = INF;
		int cur;
		ok = true;
		for (int j = 0; j < s; j++) {
			if (!vis[j] && d[j] != INF) {
				if (d[j] < Min) {
					Min = d[j];
					cur = j;
				}
			}
		}
		if (Min == INF) {
			ok = false;
			break;
		}
		
		vis[cur] = true;
		ans += Min;
		for (size_t j = 0; j < adjList[cur].size(); j++) {
			Edge edge = edges[adjList[cur][j]];
			int v = edge.to;
			int cost = edge.c;
			if (!vis[v]) {
				if (cost < d[v]) {
					d[v] = cost;
				}
			}
		}
	}
	
	if (!ok) {
		printf("Impossible\n");
	} else {
		printf("%d\n", ans);
	}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kgduu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值