首页 > 代码库 > UVA 1048 - Low Cost Air Travel(最短路)

UVA 1048 - Low Cost Air Travel(最短路)

UVA 1048 - Low Cost Air Travel

题目链接

题意:给定一些联票,在给定一些行程,要求这些行程的最小代价

思路:最短路,一张联票对应几个城市就拆成多少条边,结点表示的是当前完成形成i,在城市j的状态,这样去进行最短路,注意这题有坑点,就是城市编号可能很大,所以进行各种hash

代码:

#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <map>
using namespace std;

const int MAXNODE = 50005;
const int MAXEDGE = 1000005;

typedef int Type;
const Type INF = 0x3f3f3f3f;

struct Edge {
	int u, v, id;
	Type dist;
	Edge() {}
	Edge(int u, int v, Type dist, int id) {
		this->u = u;
		this->v = v;
		this->dist = dist;
		this->id = id;
	}
};

struct HeapNode {
	Type d;
	int u;
	HeapNode() {}
	HeapNode(Type d, int u) {
		this->d = d;
		this->u = u;
	}
	bool operator < (const HeapNode& c) const {
		return d > c.d;
	}
};

struct Dijkstra {
	int n, m;
	Edge edges[MAXEDGE];
	int first[MAXNODE];
	int next[MAXEDGE];
	bool done[MAXNODE];
	Type d[MAXNODE];
	int p[MAXNODE];

	void init(int n) {
		this->n = n;
		memset(first, -1, sizeof(first));
		m = 0;
	}

	void add_Edge(int u, int v, Type dist, int id) {
		edges[m] = Edge(u, v, dist, id);
		next[m] = first[u];
		first[u] = m++;
	}

	void print(int e) {//shun xu
		if (p[e] == -1)
			return;
		print(edges[p[e]].u);
		printf(" %d", edges[p[e]].id);
	}

	void dijkstra(int s) {
		priority_queue<HeapNode> Q;
		for (int i = 0; i < n; i++) d[i] = INF;
		d[s] = 0;
		p[s] = -1;
		memset(done, false, sizeof(done));
		Q.push(HeapNode(0, s));
		while (!Q.empty()) {
			HeapNode x = Q.top(); Q.pop();
			int u = x.u;
			if (done[u]) continue;
			done[u] = true;
			for (int i = first[u]; i != -1; i = next[i]) {
				Edge& e = edges[i];
				if (d[e.v] > d[u] + e.dist) {
					d[e.v] = d[u] + e.dist;
					p[e.v] = i;
					Q.push(HeapNode(d[e.v], e.v));
				}
			}
		}
	}
} gao;

const int N = 25;

int n;
struct Ticket {
	int val, hn, h[N];
} ti[N], tour;

int id[15][5005];
map<int, int> hash;
int cn;

int get2(int city) {
	if (!hash.count(city)) hash[city] = cn++;
	return hash[city];
}

int get(int num, int city) {
	int tmp = get2(city);
	if (id[num][tmp] == -1) id[num][tmp] = gao.n++;
	return id[num][tmp];
}
void solve() {
	cn = 0;
	hash.clear();
	gao.init(0);
	memset(id, -1, sizeof(id));
	scanf("%d", &tour.hn);
	for (int i = 1; i <= tour.hn; i++)
		scanf("%d", &tour.h[i]);
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < tour.hn; j++) {
			int u = j;
			for (int k = 0; k < ti[i].hn; k++) {
				if (ti[i].h[k] == tour.h[u + 1])
					u++;
	//			printf("%d %d %d %d %d\n", j, ti[i].h[0], u, ti[i].h[k], ti[i].val);
				gao.add_Edge(get(j, ti[i].h[0]), get(u, ti[i].h[k]), ti[i].val, i + 1);
				if (u == tour.hn) break;
			}
		}
	}
	//printf("%d %d %d\n", tour.h[1], tour.hn, tour.h[tour.hn]);
	gao.dijkstra(get(0, tour.h[1]));
	printf("Cost = %d\n", gao.d[get(tour.hn, tour.h[tour.hn])]);
	printf("  Tickets used:");
	gao.print(get(tour.hn, tour.h[tour.hn]));
	printf("\n");
}

int main() {
	int cas = 0;
	while (~scanf("%d", &n) && n) {
		cas++;
		for (int i = 0; i < n; i++) {
			scanf("%d", &ti[i].val);
			scanf("%d", &ti[i].hn);
			for (int j = 0; j < ti[i].hn; j++)
				scanf("%d", &ti[i].h[j]);
		}
		int q;
		scanf("%d", &q);
		for (int i = 1; i <= q; i++) {
			printf("Case %d, Trip %d: ", cas, i);
			solve();
		}
	}
	return 0;
}


UVA 1048 - Low Cost Air Travel(最短路)