題目鏈接
題意:給定一些聯票,在給定一些行程,要求這些行程的最小代價
思路:最短路,一張聯票對應幾個城市就拆成多少條邊,結點表示的是當前完成形成i,在城市j的狀態,這樣去進行最短路,注意這題有坑點,就是城市編號可能很大,所以進行各種hash
代碼:
#include #include #include #include #include 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 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 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 11210 Chinese Mahjong(暴力枚舉
題目 設A1,A2,…,An為矩陣序列,
ProblemAChess Queen Input:
本文譯自Gigi Sayfan在
Problem E Watering Grass I
題意:輸入兩組數據,分別是前序遍歷序列和中序遍歷序列,